How to retrieve values from a normalised MySQL 5.7 structure that match certain criterias












1















I am trying to normalise my MySQL 5.7 data shema and strugle with replacing the SQL queries:



At the moment there is one table containing all attributes of each article:



article_id | title | ref_id | dial_c_id


The task is to retrieve all articles which match two given attributes (ref_id and dial_c_id) and also retrieve all their other attributes.



With just one table, this is straightforward:



SELECT *
FROM test.articles_test
WHERE
ref_id = '127712'
AND dial_c_id = 51


Now in my effort to normalise, I have created a second table, which stores the attributes of each article and removed the ones in table articles:



table 1:



article_id | title 


table 2:



article_id | attr_group | attribute
1 ref_id 51
1 dial_c_id 33
1 another 5
2 ..


I would like to retrieve all article details including ALL attributes which match ref_id and dial_c_id with this two table shema.



Somehow like this:



SELECT 
a.article_id,
a.title,
attr.*
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
AND ref_id = '127712'
AND dial_c_id = 51


How can this be done?










share|improve this question

























  • What do you mean exactly? Given a ref_id and a dial_c_id, you want to retrieve all the rows of table_2 matching the relative article_id?

    – Ass3mbler
    Jan 1 at 17:16











  • I want all article ids, titles, attributes that match those two attributes. One article might have 20 different attributes and I need all those. Without normalization it is just select *

    – merlin
    Jan 1 at 17:19











  • So... Is your query running ok and producing the correct results ?

    – GMB
    Jan 1 at 17:20
















1















I am trying to normalise my MySQL 5.7 data shema and strugle with replacing the SQL queries:



At the moment there is one table containing all attributes of each article:



article_id | title | ref_id | dial_c_id


The task is to retrieve all articles which match two given attributes (ref_id and dial_c_id) and also retrieve all their other attributes.



With just one table, this is straightforward:



SELECT *
FROM test.articles_test
WHERE
ref_id = '127712'
AND dial_c_id = 51


Now in my effort to normalise, I have created a second table, which stores the attributes of each article and removed the ones in table articles:



table 1:



article_id | title 


table 2:



article_id | attr_group | attribute
1 ref_id 51
1 dial_c_id 33
1 another 5
2 ..


I would like to retrieve all article details including ALL attributes which match ref_id and dial_c_id with this two table shema.



Somehow like this:



SELECT 
a.article_id,
a.title,
attr.*
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
AND ref_id = '127712'
AND dial_c_id = 51


How can this be done?










share|improve this question

























  • What do you mean exactly? Given a ref_id and a dial_c_id, you want to retrieve all the rows of table_2 matching the relative article_id?

    – Ass3mbler
    Jan 1 at 17:16











  • I want all article ids, titles, attributes that match those two attributes. One article might have 20 different attributes and I need all those. Without normalization it is just select *

    – merlin
    Jan 1 at 17:19











  • So... Is your query running ok and producing the correct results ?

    – GMB
    Jan 1 at 17:20














1












1








1








I am trying to normalise my MySQL 5.7 data shema and strugle with replacing the SQL queries:



At the moment there is one table containing all attributes of each article:



article_id | title | ref_id | dial_c_id


The task is to retrieve all articles which match two given attributes (ref_id and dial_c_id) and also retrieve all their other attributes.



With just one table, this is straightforward:



SELECT *
FROM test.articles_test
WHERE
ref_id = '127712'
AND dial_c_id = 51


Now in my effort to normalise, I have created a second table, which stores the attributes of each article and removed the ones in table articles:



table 1:



article_id | title 


table 2:



article_id | attr_group | attribute
1 ref_id 51
1 dial_c_id 33
1 another 5
2 ..


I would like to retrieve all article details including ALL attributes which match ref_id and dial_c_id with this two table shema.



Somehow like this:



SELECT 
a.article_id,
a.title,
attr.*
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
AND ref_id = '127712'
AND dial_c_id = 51


How can this be done?










share|improve this question
















I am trying to normalise my MySQL 5.7 data shema and strugle with replacing the SQL queries:



At the moment there is one table containing all attributes of each article:



article_id | title | ref_id | dial_c_id


The task is to retrieve all articles which match two given attributes (ref_id and dial_c_id) and also retrieve all their other attributes.



With just one table, this is straightforward:



SELECT *
FROM test.articles_test
WHERE
ref_id = '127712'
AND dial_c_id = 51


Now in my effort to normalise, I have created a second table, which stores the attributes of each article and removed the ones in table articles:



table 1:



article_id | title 


table 2:



article_id | attr_group | attribute
1 ref_id 51
1 dial_c_id 33
1 another 5
2 ..


I would like to retrieve all article details including ALL attributes which match ref_id and dial_c_id with this two table shema.



Somehow like this:



SELECT 
a.article_id,
a.title,
attr.*
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
AND ref_id = '127712'
AND dial_c_id = 51


How can this be done?







mysql entity-attribute-value






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 1 at 17:18









Bill Karwin

382k64518674




382k64518674










asked Jan 1 at 17:05









merlinmerlin

7171921




7171921













  • What do you mean exactly? Given a ref_id and a dial_c_id, you want to retrieve all the rows of table_2 matching the relative article_id?

    – Ass3mbler
    Jan 1 at 17:16











  • I want all article ids, titles, attributes that match those two attributes. One article might have 20 different attributes and I need all those. Without normalization it is just select *

    – merlin
    Jan 1 at 17:19











  • So... Is your query running ok and producing the correct results ?

    – GMB
    Jan 1 at 17:20



















  • What do you mean exactly? Given a ref_id and a dial_c_id, you want to retrieve all the rows of table_2 matching the relative article_id?

    – Ass3mbler
    Jan 1 at 17:16











  • I want all article ids, titles, attributes that match those two attributes. One article might have 20 different attributes and I need all those. Without normalization it is just select *

    – merlin
    Jan 1 at 17:19











  • So... Is your query running ok and producing the correct results ?

    – GMB
    Jan 1 at 17:20

















What do you mean exactly? Given a ref_id and a dial_c_id, you want to retrieve all the rows of table_2 matching the relative article_id?

– Ass3mbler
Jan 1 at 17:16





What do you mean exactly? Given a ref_id and a dial_c_id, you want to retrieve all the rows of table_2 matching the relative article_id?

– Ass3mbler
Jan 1 at 17:16













I want all article ids, titles, attributes that match those two attributes. One article might have 20 different attributes and I need all those. Without normalization it is just select *

– merlin
Jan 1 at 17:19





I want all article ids, titles, attributes that match those two attributes. One article might have 20 different attributes and I need all those. Without normalization it is just select *

– merlin
Jan 1 at 17:19













So... Is your query running ok and producing the correct results ?

– GMB
Jan 1 at 17:20





So... Is your query running ok and producing the correct results ?

– GMB
Jan 1 at 17:20












1 Answer
1






active

oldest

votes


















3














You have used an Entity-Attribute-Value table to record your attributes.



This is the opposite of normalization.



Name the rule of normalization that guided you to put different attributes into the same column. You can't, because this is not a normalization practice.



To accomplish your query with your current EAV design, you need to pivot the result so you get something as if you had your original table.



SELECT * FROM (
SELECT
a.article_id,
a.title,
MAX(CASE attr_group WHEN 'ref_id' THEN attribute END) AS ref_id,
MAX(CASE attr_group WHEN 'dial_c_id' THEN attribute END) AS dial_c_id
-- ...others...
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
GROUP BY a.article_id, a.title) AS pivot
WHERE pivot.ref_id = '127712'
AND pivot.dial_c_id = 51


While the above query can produce the result you want, the performance will be terrible. It has to create a temp table for the subquery, containing all data from both tables, then apply the WHERE clause against the temp table.



You're really better off with each attribute in its own column in your original table.





I understand that you are trying to allow for many attributes in the future. This is a common problem.



See my answer to
How to design a product table for many kinds of product where each product has many parameters



But you shouldn't call it "normalised," because it isn't. It's not even denormalised. It's derelational.



You can't just use words to describe anything you want — especially not the opposite of what the word means. I can't let the air out of my bicycle tire and say "I'm inflating it."



You commented that you're trying to make your database "scalable." You also misunderstand what the word "scalable" means. By using EAV, you're creating a structure where the queries needed are difficult to write and inefficient to execute, and the data takes 10x space. It's the opposite of scalable.



What you mean is that you're trying to create a system that is extensible. This is complex to implement in SQL, but I describe several solutions in the other Stack Overflow answer to which I linked. You might also like my presentation Extensible Data Modeling with MySQL.






share|improve this answer


























  • My reasoning doing this is to create a system that scales. There might be 100 more different attribute groups in the future and with one table I would need to create a new column each time I introduce a new one.

    – merlin
    Jan 1 at 17:31






  • 1





    Thank you your extensive updated answer. I think you nailed it by calling it "extensible". Regarding my example, I must say that this two are only the simplified version, as the shema contains now 4 tables. One for naming the groups, one for naming the attributes. So the t in my example contains ids in real. Thank you for the links, I will have a closer look and try to find a better way of designing my app.

    – merlin
    Jan 1 at 19:16











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53997340%2fhow-to-retrieve-values-from-a-normalised-mysql-5-7-structure-that-match-certain%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














You have used an Entity-Attribute-Value table to record your attributes.



This is the opposite of normalization.



Name the rule of normalization that guided you to put different attributes into the same column. You can't, because this is not a normalization practice.



To accomplish your query with your current EAV design, you need to pivot the result so you get something as if you had your original table.



SELECT * FROM (
SELECT
a.article_id,
a.title,
MAX(CASE attr_group WHEN 'ref_id' THEN attribute END) AS ref_id,
MAX(CASE attr_group WHEN 'dial_c_id' THEN attribute END) AS dial_c_id
-- ...others...
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
GROUP BY a.article_id, a.title) AS pivot
WHERE pivot.ref_id = '127712'
AND pivot.dial_c_id = 51


While the above query can produce the result you want, the performance will be terrible. It has to create a temp table for the subquery, containing all data from both tables, then apply the WHERE clause against the temp table.



You're really better off with each attribute in its own column in your original table.





I understand that you are trying to allow for many attributes in the future. This is a common problem.



See my answer to
How to design a product table for many kinds of product where each product has many parameters



But you shouldn't call it "normalised," because it isn't. It's not even denormalised. It's derelational.



You can't just use words to describe anything you want — especially not the opposite of what the word means. I can't let the air out of my bicycle tire and say "I'm inflating it."



You commented that you're trying to make your database "scalable." You also misunderstand what the word "scalable" means. By using EAV, you're creating a structure where the queries needed are difficult to write and inefficient to execute, and the data takes 10x space. It's the opposite of scalable.



What you mean is that you're trying to create a system that is extensible. This is complex to implement in SQL, but I describe several solutions in the other Stack Overflow answer to which I linked. You might also like my presentation Extensible Data Modeling with MySQL.






share|improve this answer


























  • My reasoning doing this is to create a system that scales. There might be 100 more different attribute groups in the future and with one table I would need to create a new column each time I introduce a new one.

    – merlin
    Jan 1 at 17:31






  • 1





    Thank you your extensive updated answer. I think you nailed it by calling it "extensible". Regarding my example, I must say that this two are only the simplified version, as the shema contains now 4 tables. One for naming the groups, one for naming the attributes. So the t in my example contains ids in real. Thank you for the links, I will have a closer look and try to find a better way of designing my app.

    – merlin
    Jan 1 at 19:16
















3














You have used an Entity-Attribute-Value table to record your attributes.



This is the opposite of normalization.



Name the rule of normalization that guided you to put different attributes into the same column. You can't, because this is not a normalization practice.



To accomplish your query with your current EAV design, you need to pivot the result so you get something as if you had your original table.



SELECT * FROM (
SELECT
a.article_id,
a.title,
MAX(CASE attr_group WHEN 'ref_id' THEN attribute END) AS ref_id,
MAX(CASE attr_group WHEN 'dial_c_id' THEN attribute END) AS dial_c_id
-- ...others...
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
GROUP BY a.article_id, a.title) AS pivot
WHERE pivot.ref_id = '127712'
AND pivot.dial_c_id = 51


While the above query can produce the result you want, the performance will be terrible. It has to create a temp table for the subquery, containing all data from both tables, then apply the WHERE clause against the temp table.



You're really better off with each attribute in its own column in your original table.





I understand that you are trying to allow for many attributes in the future. This is a common problem.



See my answer to
How to design a product table for many kinds of product where each product has many parameters



But you shouldn't call it "normalised," because it isn't. It's not even denormalised. It's derelational.



You can't just use words to describe anything you want — especially not the opposite of what the word means. I can't let the air out of my bicycle tire and say "I'm inflating it."



You commented that you're trying to make your database "scalable." You also misunderstand what the word "scalable" means. By using EAV, you're creating a structure where the queries needed are difficult to write and inefficient to execute, and the data takes 10x space. It's the opposite of scalable.



What you mean is that you're trying to create a system that is extensible. This is complex to implement in SQL, but I describe several solutions in the other Stack Overflow answer to which I linked. You might also like my presentation Extensible Data Modeling with MySQL.






share|improve this answer


























  • My reasoning doing this is to create a system that scales. There might be 100 more different attribute groups in the future and with one table I would need to create a new column each time I introduce a new one.

    – merlin
    Jan 1 at 17:31






  • 1





    Thank you your extensive updated answer. I think you nailed it by calling it "extensible". Regarding my example, I must say that this two are only the simplified version, as the shema contains now 4 tables. One for naming the groups, one for naming the attributes. So the t in my example contains ids in real. Thank you for the links, I will have a closer look and try to find a better way of designing my app.

    – merlin
    Jan 1 at 19:16














3












3








3







You have used an Entity-Attribute-Value table to record your attributes.



This is the opposite of normalization.



Name the rule of normalization that guided you to put different attributes into the same column. You can't, because this is not a normalization practice.



To accomplish your query with your current EAV design, you need to pivot the result so you get something as if you had your original table.



SELECT * FROM (
SELECT
a.article_id,
a.title,
MAX(CASE attr_group WHEN 'ref_id' THEN attribute END) AS ref_id,
MAX(CASE attr_group WHEN 'dial_c_id' THEN attribute END) AS dial_c_id
-- ...others...
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
GROUP BY a.article_id, a.title) AS pivot
WHERE pivot.ref_id = '127712'
AND pivot.dial_c_id = 51


While the above query can produce the result you want, the performance will be terrible. It has to create a temp table for the subquery, containing all data from both tables, then apply the WHERE clause against the temp table.



You're really better off with each attribute in its own column in your original table.





I understand that you are trying to allow for many attributes in the future. This is a common problem.



See my answer to
How to design a product table for many kinds of product where each product has many parameters



But you shouldn't call it "normalised," because it isn't. It's not even denormalised. It's derelational.



You can't just use words to describe anything you want — especially not the opposite of what the word means. I can't let the air out of my bicycle tire and say "I'm inflating it."



You commented that you're trying to make your database "scalable." You also misunderstand what the word "scalable" means. By using EAV, you're creating a structure where the queries needed are difficult to write and inefficient to execute, and the data takes 10x space. It's the opposite of scalable.



What you mean is that you're trying to create a system that is extensible. This is complex to implement in SQL, but I describe several solutions in the other Stack Overflow answer to which I linked. You might also like my presentation Extensible Data Modeling with MySQL.






share|improve this answer















You have used an Entity-Attribute-Value table to record your attributes.



This is the opposite of normalization.



Name the rule of normalization that guided you to put different attributes into the same column. You can't, because this is not a normalization practice.



To accomplish your query with your current EAV design, you need to pivot the result so you get something as if you had your original table.



SELECT * FROM (
SELECT
a.article_id,
a.title,
MAX(CASE attr_group WHEN 'ref_id' THEN attribute END) AS ref_id,
MAX(CASE attr_group WHEN 'dial_c_id' THEN attribute END) AS dial_c_id
-- ...others...
FROM test.articles_test a
INNER JOIN attributes attr ON a.article_id = attr.article_id
GROUP BY a.article_id, a.title) AS pivot
WHERE pivot.ref_id = '127712'
AND pivot.dial_c_id = 51


While the above query can produce the result you want, the performance will be terrible. It has to create a temp table for the subquery, containing all data from both tables, then apply the WHERE clause against the temp table.



You're really better off with each attribute in its own column in your original table.





I understand that you are trying to allow for many attributes in the future. This is a common problem.



See my answer to
How to design a product table for many kinds of product where each product has many parameters



But you shouldn't call it "normalised," because it isn't. It's not even denormalised. It's derelational.



You can't just use words to describe anything you want — especially not the opposite of what the word means. I can't let the air out of my bicycle tire and say "I'm inflating it."



You commented that you're trying to make your database "scalable." You also misunderstand what the word "scalable" means. By using EAV, you're creating a structure where the queries needed are difficult to write and inefficient to execute, and the data takes 10x space. It's the opposite of scalable.



What you mean is that you're trying to create a system that is extensible. This is complex to implement in SQL, but I describe several solutions in the other Stack Overflow answer to which I linked. You might also like my presentation Extensible Data Modeling with MySQL.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 1 at 17:45

























answered Jan 1 at 17:25









Bill KarwinBill Karwin

382k64518674




382k64518674













  • My reasoning doing this is to create a system that scales. There might be 100 more different attribute groups in the future and with one table I would need to create a new column each time I introduce a new one.

    – merlin
    Jan 1 at 17:31






  • 1





    Thank you your extensive updated answer. I think you nailed it by calling it "extensible". Regarding my example, I must say that this two are only the simplified version, as the shema contains now 4 tables. One for naming the groups, one for naming the attributes. So the t in my example contains ids in real. Thank you for the links, I will have a closer look and try to find a better way of designing my app.

    – merlin
    Jan 1 at 19:16



















  • My reasoning doing this is to create a system that scales. There might be 100 more different attribute groups in the future and with one table I would need to create a new column each time I introduce a new one.

    – merlin
    Jan 1 at 17:31






  • 1





    Thank you your extensive updated answer. I think you nailed it by calling it "extensible". Regarding my example, I must say that this two are only the simplified version, as the shema contains now 4 tables. One for naming the groups, one for naming the attributes. So the t in my example contains ids in real. Thank you for the links, I will have a closer look and try to find a better way of designing my app.

    – merlin
    Jan 1 at 19:16

















My reasoning doing this is to create a system that scales. There might be 100 more different attribute groups in the future and with one table I would need to create a new column each time I introduce a new one.

– merlin
Jan 1 at 17:31





My reasoning doing this is to create a system that scales. There might be 100 more different attribute groups in the future and with one table I would need to create a new column each time I introduce a new one.

– merlin
Jan 1 at 17:31




1




1





Thank you your extensive updated answer. I think you nailed it by calling it "extensible". Regarding my example, I must say that this two are only the simplified version, as the shema contains now 4 tables. One for naming the groups, one for naming the attributes. So the t in my example contains ids in real. Thank you for the links, I will have a closer look and try to find a better way of designing my app.

– merlin
Jan 1 at 19:16





Thank you your extensive updated answer. I think you nailed it by calling it "extensible". Regarding my example, I must say that this two are only the simplified version, as the shema contains now 4 tables. One for naming the groups, one for naming the attributes. So the t in my example contains ids in real. Thank you for the links, I will have a closer look and try to find a better way of designing my app.

– merlin
Jan 1 at 19:16




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53997340%2fhow-to-retrieve-values-from-a-normalised-mysql-5-7-structure-that-match-certain%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

Npm cannot find a required file even through it is in the searched directory