Select column based on column name stored in another table










0















I am trying to get a cell value from another table (UserTable) for which the column of the cell is specified in the original table (DataTable). The cell value is going to be used to calculate a score which will then determine the ordering of the query results.



UserTable:
+--------+------+------+------+
| userid | c1 | c2 | c3 |
+--------+------+------+------+
| id1 | 0 | 1 | 1 |
| id2 | 0 | 0 | 1 |
| id3 | 1 | 0 | 0 |
| id4 | 1 | 1 | 0 |
+--------+------+------+------+

DataTable:
+--------+------+------+------+
| id | ColA | ColB | ColC |
+--------+------+------+------+
| 1 | A | B | c1 |
| 2 | D | E | c3 |
| 3 | G | H | c2 |
| 4 | J | K | c3 |
+--------+------+------+------+


My current, not working, query is:



SELECT *, 
(SELECT DataTable.ColC
FROM UserTable
WHERE UserTable.userid = 'some_user_id') AS score
FROM DataTable
ORDER BY score DESC


But this doesn't select the appropriate column in UserTable and instead returns the string value contained in ColC.



The expected output:
If 'some_user_id' was set to 'id2' for example. The the expected output would be:



+--------+------+------+------+------+
| id | ColA | ColB | ColC | score|
+--------+------+------+------+------+
| 2 | D | E | c3 | 1 |
| 4 | J | K | c3 | 1 |
| 1 | A | B | c1 | 0 |
| 3 | G | H | c2 | 0 |
+--------+------+------+------+------+


where the score column is simply the lookup of the value from the UserTable.



Is it possible to solve this problem?










share|improve this question
























  • I have just updated it now

    – Fowler
    Nov 13 '18 at 11:07
















0















I am trying to get a cell value from another table (UserTable) for which the column of the cell is specified in the original table (DataTable). The cell value is going to be used to calculate a score which will then determine the ordering of the query results.



UserTable:
+--------+------+------+------+
| userid | c1 | c2 | c3 |
+--------+------+------+------+
| id1 | 0 | 1 | 1 |
| id2 | 0 | 0 | 1 |
| id3 | 1 | 0 | 0 |
| id4 | 1 | 1 | 0 |
+--------+------+------+------+

DataTable:
+--------+------+------+------+
| id | ColA | ColB | ColC |
+--------+------+------+------+
| 1 | A | B | c1 |
| 2 | D | E | c3 |
| 3 | G | H | c2 |
| 4 | J | K | c3 |
+--------+------+------+------+


My current, not working, query is:



SELECT *, 
(SELECT DataTable.ColC
FROM UserTable
WHERE UserTable.userid = 'some_user_id') AS score
FROM DataTable
ORDER BY score DESC


But this doesn't select the appropriate column in UserTable and instead returns the string value contained in ColC.



The expected output:
If 'some_user_id' was set to 'id2' for example. The the expected output would be:



+--------+------+------+------+------+
| id | ColA | ColB | ColC | score|
+--------+------+------+------+------+
| 2 | D | E | c3 | 1 |
| 4 | J | K | c3 | 1 |
| 1 | A | B | c1 | 0 |
| 3 | G | H | c2 | 0 |
+--------+------+------+------+------+


where the score column is simply the lookup of the value from the UserTable.



Is it possible to solve this problem?










share|improve this question
























  • I have just updated it now

    – Fowler
    Nov 13 '18 at 11:07














0












0








0








I am trying to get a cell value from another table (UserTable) for which the column of the cell is specified in the original table (DataTable). The cell value is going to be used to calculate a score which will then determine the ordering of the query results.



UserTable:
+--------+------+------+------+
| userid | c1 | c2 | c3 |
+--------+------+------+------+
| id1 | 0 | 1 | 1 |
| id2 | 0 | 0 | 1 |
| id3 | 1 | 0 | 0 |
| id4 | 1 | 1 | 0 |
+--------+------+------+------+

DataTable:
+--------+------+------+------+
| id | ColA | ColB | ColC |
+--------+------+------+------+
| 1 | A | B | c1 |
| 2 | D | E | c3 |
| 3 | G | H | c2 |
| 4 | J | K | c3 |
+--------+------+------+------+


My current, not working, query is:



SELECT *, 
(SELECT DataTable.ColC
FROM UserTable
WHERE UserTable.userid = 'some_user_id') AS score
FROM DataTable
ORDER BY score DESC


But this doesn't select the appropriate column in UserTable and instead returns the string value contained in ColC.



The expected output:
If 'some_user_id' was set to 'id2' for example. The the expected output would be:



+--------+------+------+------+------+
| id | ColA | ColB | ColC | score|
+--------+------+------+------+------+
| 2 | D | E | c3 | 1 |
| 4 | J | K | c3 | 1 |
| 1 | A | B | c1 | 0 |
| 3 | G | H | c2 | 0 |
+--------+------+------+------+------+


where the score column is simply the lookup of the value from the UserTable.



Is it possible to solve this problem?










share|improve this question
















I am trying to get a cell value from another table (UserTable) for which the column of the cell is specified in the original table (DataTable). The cell value is going to be used to calculate a score which will then determine the ordering of the query results.



UserTable:
+--------+------+------+------+
| userid | c1 | c2 | c3 |
+--------+------+------+------+
| id1 | 0 | 1 | 1 |
| id2 | 0 | 0 | 1 |
| id3 | 1 | 0 | 0 |
| id4 | 1 | 1 | 0 |
+--------+------+------+------+

DataTable:
+--------+------+------+------+
| id | ColA | ColB | ColC |
+--------+------+------+------+
| 1 | A | B | c1 |
| 2 | D | E | c3 |
| 3 | G | H | c2 |
| 4 | J | K | c3 |
+--------+------+------+------+


My current, not working, query is:



SELECT *, 
(SELECT DataTable.ColC
FROM UserTable
WHERE UserTable.userid = 'some_user_id') AS score
FROM DataTable
ORDER BY score DESC


But this doesn't select the appropriate column in UserTable and instead returns the string value contained in ColC.



The expected output:
If 'some_user_id' was set to 'id2' for example. The the expected output would be:



+--------+------+------+------+------+
| id | ColA | ColB | ColC | score|
+--------+------+------+------+------+
| 2 | D | E | c3 | 1 |
| 4 | J | K | c3 | 1 |
| 1 | A | B | c1 | 0 |
| 3 | G | H | c2 | 0 |
+--------+------+------+------+------+


where the score column is simply the lookup of the value from the UserTable.



Is it possible to solve this problem?







mysql sql






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 6:41









Salman A

180k66339431




180k66339431










asked Nov 13 '18 at 10:57









FowlerFowler

385




385












  • I have just updated it now

    – Fowler
    Nov 13 '18 at 11:07


















  • I have just updated it now

    – Fowler
    Nov 13 '18 at 11:07

















I have just updated it now

– Fowler
Nov 13 '18 at 11:07






I have just updated it now

– Fowler
Nov 13 '18 at 11:07













3 Answers
3






active

oldest

votes


















1














You cannot do this dynamically. But you can build a CASE statement that maps column names to columns:



SELECT DataTable.*, (
SELECT CASE DataTable.ColC
WHEN 'c1' THEN UserTable.c1
WHEN 'c2' THEN UserTable.c3
WHEN 'c3' THEN UserTable.c3
END
FROM UserTable
WHERE UserTable.userid = 'id2'
) AS score
FROM DataTable
ORDER BY score DESC





share|improve this answer























  • Thank you very much for your solution, I appreciate it! Although it is slightly annoying it cannot be done dynamically as my columns changes over time.

    – Fowler
    Nov 13 '18 at 11:25


















0














Declare @expr nvarchar(max); 
Declare @value nvarchar(max);
DECLARE db_cursor CURSOR
FOR Select colC from dbo.DataTable;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @value;
Set @expr = 'Select ' + @value;
WHILE @@FETCH_STATUS = 0
BEGIN
Set @expr += ',' + @value
FETCH NEXT FROM db_cursor INTO @value;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;

EXEC (@expr + ' from dbo.UserTable')





share|improve this answer























  • Thank you for you response. Have you tested this code / what version of mysql are you using? On 5.6 the syntax doesn't checkout. For example should the first two Declare statements not instead be SET statements?

    – Fowler
    Nov 13 '18 at 11:39


















0














I like to express this by unpivoting the user table:



select dt.*, uts.score
from datatable dt left join
((select ut.userid, 'c1' as which, c1 as score
from usertable ut
) union all
(select ut.userid, 'c2' as which, c2 as score
from usertable ut
) union all
(select ut.userid, 'c3' as which, c3 as score
from usertable ut
)
) uts
on dt.colc = uts.which
where uts.userid = ?;


The reason I prefer this approach is because the subquery suggests the table that you really need. You should not be storing the different score values in columns. You should have a userScores table with one row per user and per score.






share|improve this answer























  • You make a good point. I think I am going to make a table for each userid, with a row for each column (c1, c2, c3) along with the corresponding score. For my application there are thousands of these columns named c1..cN

    – Fowler
    Nov 13 '18 at 11:56










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%2f53279482%2fselect-column-based-on-column-name-stored-in-another-table%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














You cannot do this dynamically. But you can build a CASE statement that maps column names to columns:



SELECT DataTable.*, (
SELECT CASE DataTable.ColC
WHEN 'c1' THEN UserTable.c1
WHEN 'c2' THEN UserTable.c3
WHEN 'c3' THEN UserTable.c3
END
FROM UserTable
WHERE UserTable.userid = 'id2'
) AS score
FROM DataTable
ORDER BY score DESC





share|improve this answer























  • Thank you very much for your solution, I appreciate it! Although it is slightly annoying it cannot be done dynamically as my columns changes over time.

    – Fowler
    Nov 13 '18 at 11:25















1














You cannot do this dynamically. But you can build a CASE statement that maps column names to columns:



SELECT DataTable.*, (
SELECT CASE DataTable.ColC
WHEN 'c1' THEN UserTable.c1
WHEN 'c2' THEN UserTable.c3
WHEN 'c3' THEN UserTable.c3
END
FROM UserTable
WHERE UserTable.userid = 'id2'
) AS score
FROM DataTable
ORDER BY score DESC





share|improve this answer























  • Thank you very much for your solution, I appreciate it! Although it is slightly annoying it cannot be done dynamically as my columns changes over time.

    – Fowler
    Nov 13 '18 at 11:25













1












1








1







You cannot do this dynamically. But you can build a CASE statement that maps column names to columns:



SELECT DataTable.*, (
SELECT CASE DataTable.ColC
WHEN 'c1' THEN UserTable.c1
WHEN 'c2' THEN UserTable.c3
WHEN 'c3' THEN UserTable.c3
END
FROM UserTable
WHERE UserTable.userid = 'id2'
) AS score
FROM DataTable
ORDER BY score DESC





share|improve this answer













You cannot do this dynamically. But you can build a CASE statement that maps column names to columns:



SELECT DataTable.*, (
SELECT CASE DataTable.ColC
WHEN 'c1' THEN UserTable.c1
WHEN 'c2' THEN UserTable.c3
WHEN 'c3' THEN UserTable.c3
END
FROM UserTable
WHERE UserTable.userid = 'id2'
) AS score
FROM DataTable
ORDER BY score DESC






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 11:17









Salman ASalman A

180k66339431




180k66339431












  • Thank you very much for your solution, I appreciate it! Although it is slightly annoying it cannot be done dynamically as my columns changes over time.

    – Fowler
    Nov 13 '18 at 11:25

















  • Thank you very much for your solution, I appreciate it! Although it is slightly annoying it cannot be done dynamically as my columns changes over time.

    – Fowler
    Nov 13 '18 at 11:25
















Thank you very much for your solution, I appreciate it! Although it is slightly annoying it cannot be done dynamically as my columns changes over time.

– Fowler
Nov 13 '18 at 11:25





Thank you very much for your solution, I appreciate it! Although it is slightly annoying it cannot be done dynamically as my columns changes over time.

– Fowler
Nov 13 '18 at 11:25













0














Declare @expr nvarchar(max); 
Declare @value nvarchar(max);
DECLARE db_cursor CURSOR
FOR Select colC from dbo.DataTable;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @value;
Set @expr = 'Select ' + @value;
WHILE @@FETCH_STATUS = 0
BEGIN
Set @expr += ',' + @value
FETCH NEXT FROM db_cursor INTO @value;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;

EXEC (@expr + ' from dbo.UserTable')





share|improve this answer























  • Thank you for you response. Have you tested this code / what version of mysql are you using? On 5.6 the syntax doesn't checkout. For example should the first two Declare statements not instead be SET statements?

    – Fowler
    Nov 13 '18 at 11:39















0














Declare @expr nvarchar(max); 
Declare @value nvarchar(max);
DECLARE db_cursor CURSOR
FOR Select colC from dbo.DataTable;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @value;
Set @expr = 'Select ' + @value;
WHILE @@FETCH_STATUS = 0
BEGIN
Set @expr += ',' + @value
FETCH NEXT FROM db_cursor INTO @value;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;

EXEC (@expr + ' from dbo.UserTable')





share|improve this answer























  • Thank you for you response. Have you tested this code / what version of mysql are you using? On 5.6 the syntax doesn't checkout. For example should the first two Declare statements not instead be SET statements?

    – Fowler
    Nov 13 '18 at 11:39













0












0








0







Declare @expr nvarchar(max); 
Declare @value nvarchar(max);
DECLARE db_cursor CURSOR
FOR Select colC from dbo.DataTable;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @value;
Set @expr = 'Select ' + @value;
WHILE @@FETCH_STATUS = 0
BEGIN
Set @expr += ',' + @value
FETCH NEXT FROM db_cursor INTO @value;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;

EXEC (@expr + ' from dbo.UserTable')





share|improve this answer













Declare @expr nvarchar(max); 
Declare @value nvarchar(max);
DECLARE db_cursor CURSOR
FOR Select colC from dbo.DataTable;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @value;
Set @expr = 'Select ' + @value;
WHILE @@FETCH_STATUS = 0
BEGIN
Set @expr += ',' + @value
FETCH NEXT FROM db_cursor INTO @value;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;

EXEC (@expr + ' from dbo.UserTable')






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 11:23









Cosmin GheorghitaCosmin Gheorghita

1




1












  • Thank you for you response. Have you tested this code / what version of mysql are you using? On 5.6 the syntax doesn't checkout. For example should the first two Declare statements not instead be SET statements?

    – Fowler
    Nov 13 '18 at 11:39

















  • Thank you for you response. Have you tested this code / what version of mysql are you using? On 5.6 the syntax doesn't checkout. For example should the first two Declare statements not instead be SET statements?

    – Fowler
    Nov 13 '18 at 11:39
















Thank you for you response. Have you tested this code / what version of mysql are you using? On 5.6 the syntax doesn't checkout. For example should the first two Declare statements not instead be SET statements?

– Fowler
Nov 13 '18 at 11:39





Thank you for you response. Have you tested this code / what version of mysql are you using? On 5.6 the syntax doesn't checkout. For example should the first two Declare statements not instead be SET statements?

– Fowler
Nov 13 '18 at 11:39











0














I like to express this by unpivoting the user table:



select dt.*, uts.score
from datatable dt left join
((select ut.userid, 'c1' as which, c1 as score
from usertable ut
) union all
(select ut.userid, 'c2' as which, c2 as score
from usertable ut
) union all
(select ut.userid, 'c3' as which, c3 as score
from usertable ut
)
) uts
on dt.colc = uts.which
where uts.userid = ?;


The reason I prefer this approach is because the subquery suggests the table that you really need. You should not be storing the different score values in columns. You should have a userScores table with one row per user and per score.






share|improve this answer























  • You make a good point. I think I am going to make a table for each userid, with a row for each column (c1, c2, c3) along with the corresponding score. For my application there are thousands of these columns named c1..cN

    – Fowler
    Nov 13 '18 at 11:56















0














I like to express this by unpivoting the user table:



select dt.*, uts.score
from datatable dt left join
((select ut.userid, 'c1' as which, c1 as score
from usertable ut
) union all
(select ut.userid, 'c2' as which, c2 as score
from usertable ut
) union all
(select ut.userid, 'c3' as which, c3 as score
from usertable ut
)
) uts
on dt.colc = uts.which
where uts.userid = ?;


The reason I prefer this approach is because the subquery suggests the table that you really need. You should not be storing the different score values in columns. You should have a userScores table with one row per user and per score.






share|improve this answer























  • You make a good point. I think I am going to make a table for each userid, with a row for each column (c1, c2, c3) along with the corresponding score. For my application there are thousands of these columns named c1..cN

    – Fowler
    Nov 13 '18 at 11:56













0












0








0







I like to express this by unpivoting the user table:



select dt.*, uts.score
from datatable dt left join
((select ut.userid, 'c1' as which, c1 as score
from usertable ut
) union all
(select ut.userid, 'c2' as which, c2 as score
from usertable ut
) union all
(select ut.userid, 'c3' as which, c3 as score
from usertable ut
)
) uts
on dt.colc = uts.which
where uts.userid = ?;


The reason I prefer this approach is because the subquery suggests the table that you really need. You should not be storing the different score values in columns. You should have a userScores table with one row per user and per score.






share|improve this answer













I like to express this by unpivoting the user table:



select dt.*, uts.score
from datatable dt left join
((select ut.userid, 'c1' as which, c1 as score
from usertable ut
) union all
(select ut.userid, 'c2' as which, c2 as score
from usertable ut
) union all
(select ut.userid, 'c3' as which, c3 as score
from usertable ut
)
) uts
on dt.colc = uts.which
where uts.userid = ?;


The reason I prefer this approach is because the subquery suggests the table that you really need. You should not be storing the different score values in columns. You should have a userScores table with one row per user and per score.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 11:41









Gordon LinoffGordon Linoff

772k35306407




772k35306407












  • You make a good point. I think I am going to make a table for each userid, with a row for each column (c1, c2, c3) along with the corresponding score. For my application there are thousands of these columns named c1..cN

    – Fowler
    Nov 13 '18 at 11:56

















  • You make a good point. I think I am going to make a table for each userid, with a row for each column (c1, c2, c3) along with the corresponding score. For my application there are thousands of these columns named c1..cN

    – Fowler
    Nov 13 '18 at 11:56
















You make a good point. I think I am going to make a table for each userid, with a row for each column (c1, c2, c3) along with the corresponding score. For my application there are thousands of these columns named c1..cN

– Fowler
Nov 13 '18 at 11:56





You make a good point. I think I am going to make a table for each userid, with a row for each column (c1, c2, c3) along with the corresponding score. For my application there are thousands of these columns named c1..cN

– Fowler
Nov 13 '18 at 11:56

















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%2f53279482%2fselect-column-based-on-column-name-stored-in-another-table%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

Kleinkühnau

Makov (Slowakei)

Deutsches Schauspielhaus