我正在编译MySQL查询附带的HTML输出显示页面,但希望得到一些方向。任何帮助将非常感激!
背景:TaskInstance是子进程,而Tasks和Students都是父进程。每次学生注册一个任务时,TaskInstance表都会不断增长,然而Tasks表的数量是有限的,例如20个。每个任务都位于Tasks表中,并具有一些通用的特性。用户可以注册一个任务,但随后可以使用TaskInstance表为该任务分配独特的质量。TaskInstance变量包括:
- TkInstanceInfoA, TkInstanceInfoB, TkInstanceInfoC, TkInstanceInfoD允许各种描述等
- TkInstanceSide指示任务是在右侧,左侧还是没有侧(L, R或null)完成
- fkTkID告诉我们哪个任务是TaskInstance的父任务
- fkStID告诉我们哪个学生是TaskInstance的父级
数据库:
Students
1.) StID
2.) StNameFirst
3.) StNameLast
4.) StGender
5.) StPasscode
6.) fkProID
Tasks
1.) TkID
2.) TkSide (the task by nature has a side?: Y or N)
3.) TkImgML
4.) TkImgMR
5.) TkImgMC
6.) TkImgFL
7.) TkImgFR
8.) TkImgFC
9.) TkTitleSci
10.) TkTitleCom
11.) TkDesc
TaskInstance
1.) TkInstID
2.) TkInstSide (which side is the task?: L, R or null)
3.) TkInstInfoA
4.) TkInstInfoB
5.) TkInstInfoC
6.) TkInstInfoD
7.) TkInstCustomTitleSci
8.) TkInstCustomTitleCom
9.) TkInstCustomDesc
10.) TkInstOrder
11.) fkTkID
12.) fkStID
MySQL: 更新:2013年4月16日12:03 pm EST:我有SELECT和SELECT CASE颠倒,缺少逗号。现在更正,但仍然打破:
$CurrentStID = 1; // known previously
$CurrentStGender = M; // known previously
SELECT *,
CASE StGender
WHEN 'M' THEN
CASE IFNULL(TkInstSide, 'C')
WHEN 'L' THEN TkImgML
WHEN 'R' THEN TkImgMR
ELSE TkImgMC
END
WHEN 'F' THEN
CASE IFNULL(TkInstSide, 'C')
WHEN 'L' THEN TkImgFL
WHEN 'R' THEN TkImgFR
ELSE TkImgFC
END
END TkImgCase,
CASE StTitlePref
WHEN 'Common' THEN
CASE WHEN TkInstCustomTitleCom IS NULL
THEN TkTitleCom
ELSE TkInstCustomTitleCom
END
WHEN 'Scientific' THEN
CASE WHEN TkInstCustomTitleSci IS NULL
THEN TkTitleSci
ELSE TkInstCustomTitleSci
END
END TkTitleCase
FROM TaskInstance
LEFT JOIN Tasks ON fkTkID = TkID
LEFT JOIN Students ON fkStID = StID
WHERE fkStID = $CurrentStID
ORDER BY TkInstOrder
打印:
1。)检查自定义标题和描述,否则使用标准:
更新:2013年4月16日上午11:52 EST:我一直挂在自定义标题。我的调整是否有效?它似乎失败了。
if ($row['StTitlePref'] == "Common") && (strlen(trim($row['TkInstCustomTitleCom'])) > 0) { $TkTitle = $row['TkInstCustomTitleCom'] } // will be default or custom
else if ($row['StTitlePref'] == "Scientific") && (strlen(trim($row['TkInstCustomTitleSci']) > 0) { $TkTitle = $row['TkInstCustomTitleSci'] } // will be default or custom
2。)从6张图片中选择1张:
是否可以使用MySQL使用性别来消除6个图像中的3个,然后再使用PHP if/then来选择剩下的3个图像中的1个?
如果Student 's Gender (StGender)是male,并且Task有一个side (TkSide),则显示正确的图像:如果是L-side (TkInstanceSide),则显示L male image (TkImgML);如果是R侧(TkInstanceSide),则显示R男像(TkImgMR)。如果学生的性别(StGender)是男性,并且任务没有侧面(TkSide)[同时TkInstanceSide为null],则显示中心男性图像(TkImgMC)。
如果Student 's Gender (StGender)是女性,并且Task有一侧(TkSide),则显示正确的图像:如果是L侧(TkInstanceSide),则显示L女性图像(TkImgFL);如果是R侧(TkInstanceSide),则显示R女性图像(TkImgFR)。如果学生的性别(StGender)是女性,并且任务没有侧面(TkSide)[同时TkInstanceSide为null],则显示中心女性图像(TkImgFC)。
3)。显示与此实例相关的其他信息:
显示这4个变量:TkInstanceInfoA、TkInstanceInfoB、TkInstanceInfoC、TkInstanceInfoD。
所以,最终是这样的:
echo ‘<p>’ . $TkTitleCom . ‘<br>’; // show either standard title or custom title
echo $TkDesc . ‘<br>’; // show either standard description or custom description
echo $TkInstanceInfoA . ‘<br>’;
echo $TkInstanceInfoB . ‘<br>’;
echo $TkInstanceInfoC . ‘<br>’;
echo $TkInstanceInfoD . ‘<br>’;
echo $CorrectImg . ‘</p>’; // show either TkImgML, TkImgMR, TkImgMC, TkImgFL, TkImgFR or TkImgFC
4/18/2013:后续问题(类似的)
亲爱的Barmar:非常感谢你的帮助。如果您有时间,我有一个后续问题。我有一个显示页面,我只是试图从任务表拉(而不是像以前一样从TaskInstance表)。
我知道$CurrentStGender和$CurrentStTitlePref从以前的查询。我仍然希望使用CASE语句选择正确的图像(6个中的1个)和正确的标题首选项。我有一个艰难的时间试图找出如何喂养我的两个已知变量的SQL。你能帮忙吗?
// echo $CurrentStGender . ', ' . $CurrentStTitlePref;
if ($result = $mysqli->query("
SELECT *,
CASE CurrentStGender
WHEN 'M' THEN
CASE WHEN TkSide == 'Y' THEN TkImgML /* if task can be done on a side, show just the L-side
ELSE TkImgMC
END
WHEN 'F' THEN
CASE WHEN TkSide == 'Y' THEN TkImgFL /* if task can be done on a side, show just the L-side
ELSE TkImgFC
END
END TkImgCase,
CASE StTitlePref
WHEN 'Common' THEN TkTitleCom
END
WHEN 'Scientific' THEN TkTitleSci
END
END TkTitleCase
FROM Tasks
您可以在SQL:
中选择基于性别和侧面的图像。SELECT *,
CASE StGender
WHEN 'M' THEN
CASE IFNULL(TkSide, 'C')
WHEN 'L' THEN TkImgML
WHEN 'R' THEN TkImgMR
ELSE TkImgMC
END
WHEN 'F' THEN
CASE IFNULL(TkSide, 'C')
WHEN 'L' THEN TkImgFL
WHEN 'R' THEN TkImgFR
ELSE TkImgFC
END
END TkImg
FROM TaskInstance
LEFT JOIN Tasks ON fkTkID = TkID
LEFT JOIN Students ON fkStID = StID
WHERE fkStID = $CurrentStID
ORDER BY TkInstOrder
后续回答:
有两种方法可以做到这一点。一种方法是保持当前的两层CASE结构,但将列名替换为用PHP变量填充的文字(在CASE语句中允许任何表达式,因此文字与列名一样好):
CASE '$CurrentStGender'
WHEN 'M' THEN ...
WHEN 'F' THEN ...
END TkImgCase,
CASE '$CurrentStTitlePref'
WHEN 'Common' THEN TkTitleCom
END
WHEN 'Scientific' THEN TkTitleSci
END
END TkTitleCase
另一个利用了列遵循命名约定的事实,因此您可以直接插入到列名中:
$titleAbbrev = substr($CurrentStTitlePref, 0, 3);
if ($result = $mysqli->query("
SELECT *,
CASE WHEN TkSide == 'Y' THEN TkImg{$CurrentStGender}L
ELSE TkImg{$CurrentStGender}C
END TkImgCase,
TkTitle{$titleAbbrev} TkTitleCase
FROM Tasks");
(1) Print
if (strlen(trim($TkInstCustomTitleCom)) > 0) $tkTitleCom = $tkInstCustomTitleCom;
echo $tkTitleCom; // will be default or custom
(2)打印
试试这个代替if ... else
;括号内的表达式称为ternary operator
,第2行中的表达式为variable variable
:
$image = "TkImg" . $StGender . ($TkSide=='Y'?$TkInstanceSide:'C');
$imagename = $$image; // now $imagename contains the content of e.g. $TkImgMC
查看它的工作情况:http://codepad.viper-7.com/abpxbU
SQL
$sql = <<<SQL
SELECT *
FROM TaskInstance
LEFT JOIN Tasks ON fkTkID = TkID
WHERE fkStID = :stID
ORDER BY TkInstOrder
SQL;
相同但不同:
$sql = "SELECT * FROM TaskInstance LEFT JOIN Tasks ON fkTkID = TkID WHERE fkStID = :stID ORDER BY TkInstOrder";
:stID
为参数,查询为参数化查询。它对sql注入是安全的。您将使用PDO函数而不是mysql_*(已弃用)。