I'm trying to run a query for each day within a month. The portion of the query for the first of the month looks like this, and it works:
CASE
WHEN CONCAT(
Shifts.d1a,
Shifts.d1b,
Shifts.d1c,
Shifts.d1d,
Shifts.d1e,
Shifts.d1f) = "" THEN "-"
ELSE
CONCAT (
IF (Shifts.d1a='Yes','A',''),
IF (Shifts.d1b='Yes','B',''),
IF (Shifts.d1c='Yes','C',''),
IF (Shifts.d1d='Yes','D',''),
IF (Shifts.d1e='Yes','E',''),
IF (Shifts.d1f='Yes','F','')
) END AS d1,
The second day of the month would look the same, except that all the "d1" parts of the table references would be "d2," and the "END AS d1" would be "END AS d2."
I inherited the table structure; each d[n][x] gets a value of "Yes" or "". There are no nulls involved. The goal is to take separately fielded items within a day - i.e. d[n]a, d[n]b, d[n]c, etc, and concatenate them into (e.g.) "ABF" for each field that has a yes value, and if all fields are empty generate a hyphen, in column d[n].
Like I said, this works if I run 31 executions of nearly identical code. That just strikes me as ugly and unnecessary. But I've run up against the apparent wall of using concatenated strings as column names within SELECTs, as well as using variables as part of a column alias in the output. So this doesn't work:
BEGIN
DECLARE vcounter INT DEFAULT 0;
DECLARE vcolumn VARCHAR (10);
DECLARE vcolumna VARCHAR (64);
DECLARE vcolumnb VARCHAR (64);
DECLARE vcolumnc VARCHAR (64);
DECLARE vcolumnd VARCHAR (64);
DECLARE vcolumne VARCHAR (64);
DECLARE vcolumnf VARCHAR (64);
shift_loop: REPEAT
SET vcounter = vcounter + 1;
SET vcolumn = CONCAT ('d',vcounter);
SET vcolumna = CONCAT ('Shift.',vcolumn,'a');
SET vcolumnb = CONCAT ('Shift.',vcolumn,'b');
SET vcolumnc = CONCAT ('Shift.',vcolumn,'c');
SET vcolumnd = CONCAT ('Shift.',vcolumn,'d');
SET vcolumne = CONCAT ('Shift.',vcolumn,'e');
SET vcolumnf = CONCAT ('Shift.',vcolumn,'f');
SELECT
CASE
WHEN CONCAT(
vcolumna,
vcolumnb,
vcolumnc,
vcolumnd,
vcolumne,
vcolumnf) = '' THEN '-'
ELSE
CONCAT(
vcolumna,
vcolumnb,
vcolumnc,
vcolumnd,
vcolumne,
vcolumnf
)
END
AS vcolumn;
UNTIL vcounter = 1
END REPEAT;
END
Yes, I know that the CASE statement in the procedure is unnecessary -- I could just assign the results of the final CONCAT to a variable and test it against an empty value. I just left this as-is to give a better idea of what I want to do.
The result is that for each row I get a single column called "vcounter," with its contents being "Shift.d1aShift.d1bShift.d1c
" etc.
Does anyone have any suggestions?
EDITED TO ADD
OK, thanks, I checked out the suggested answer, but I can't figure out how to make it work with the WHILE statement I need. Here's what I changed my code to:
BEGIN
SET @vcounter = 0;
SET @vcounter = @vcounter + 1;
SET @vtable = 'Table_X';
SET @vcolumn = CONCAT ('d',@vcounter);
SET @vcolumna = CONCAT (@vtable,'.',@vcolumn,'a');
SET @vcolumnb = CONCAT (@vtable,'.',@vcolumn,'b');
SET @vcolumnc = CONCAT (@vtable,'.',@vcolumn,'c');
SET @vcolumnd = CONCAT (@vtable,'.',@vcolumn,'d');
SET @vcolumne = CONCAT (@vtable,'.',@vcolumn,'e');
SET @vcolumnf = CONCAT (@vtable,'.',@vcolumn,'f');
SET @vshifts = CONCAT
(@vcolumna,',',@vcolumnb,',',@vcolumnc,',',@vcolumnd,',',@vcolumne,',',@vcolumnf);
SET @vquery = CONCAT ('SELECT CASE WHEN CONCAT (',
@vshifts,
') ="" THEN "-" ELSE
CONCAT (IF(',@vcolumna,' = "Yes","A",""),
IF(',@vcolumnb,' = "Yes","B",""),
IF(',@vcolumnc,' = "Yes","C",""),
IF(',@vcolumnd,' = "Yes","D",""),
IF(',@vcolumne,' = "Yes","E",""),
IF(',@vcolumnf,' = "Yes","F","")
)END AS ',@vcolumn,' FROM ',@vtable);
PREPARE stmt FROM @vquery;
EXECUTE stmt;
END
This works nicely for a single day. Problem is, anywhere I insert a WHILE or REPEAT statement, I get bad results. The closest I've found ends up producing results that look like
d1
D
F
A
B
d2
A
AB
C
-
etc. What I want instead is
d1 d2
D A
F AB
A C
B -
I obviously don't know much about what I'm doing here, so I really appreciate any help anyone can provide. Thanks.