0

我正在为一个显示页面编译一个带有 HTML 输出的 MySQL 查询,但希望能得到一些指导。任何帮助将非常感激!

背景: TaskInstance 是孩子,而 Tasks 和 Student 都是父母。每次学生注册任务时,TaskInstance 表都会不断增长,但 Tasks 表的数量是有限的,例如 20。每个任务都位于 Tasks 表中,并具有一些通用特性。用户可以注册一项任务,然后可以使用 TaskInstance 表将独特的品质分配给该任务。TaskInstance 变量包括:

  • TkInstanceInfoA、TkInstanceInfoB、TkInstanceInfoC、TkInstanceInfoD 允许各种描述等。
  • TkInstanceSide 指示任务是在右侧、左侧完成还是没有边(L、R 或 null)
  • fkTkID 告诉我们哪个 Task 是 TaskInstance 的父级
  • fkStID 告诉我们哪个 Student 是 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:我将 SELECT AND 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:我一直在挂断自定义标题。我的调整应该起作用吗?它似乎失败了。

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.) 从六张图片中选择一张:

使用 MySQL 使用性别消除 6 张图像中的 3 张,然后使用 PHP if/then 选择剩余 3 张图像中的 1 张是否很好?

如果Student的性别(StGender)是男性,并且Task有一面(TkSide),则显示正确的图像:如果是L面(TkInstanceSide),则显示L男性图像(TkImgML);如果是 R 端 (TkInstanceSide),则显示 R 男性图像 (TkImgMR)。如果学生的性别(StGender)是男性,并且任务没有侧面(TkSide)[也 TkInstanceSide 为空],则显示中心男性图像(TkImgMC)。

如果Student的性别(StGender)是女性,并且Task有一面(TkSide),则显示正确的图像:如果是L-side(TkInstanceSide),则显示L个女性图像(TkImgFL);如果是 R 侧 (TkInstanceSide),则显示 R 女性图像 (TkImgFR)。如果学生的性别(StGender)是女性,并且任务没有侧面(TkSide)[也 TkInstanceSide 为空],则显示中心女性图像(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

2013 年 4 月 18 日:后续问题(类似)

亲爱的巴尔玛:非常感谢您的帮助。如果你有时间,我有一个后续问题。我有一个显示页面,我只是想从 Tasks 表中提取(而不是像以前那样从 TaskInstance 表中提取)。

我从上一个查询中知道 $CurrentStGender 和 $CurrentStTitlePref。我仍然想使用 CASE 语句来选择正确的图像(1 of 6)和正确的标题偏好。我很难弄清楚如何将我的两个已知变量提供给 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
4

3 回答 3

1

(1) 打印

if (strlen(trim($TkInstCustomTitleCom)) > 0) $tkTitleCom = $tkInstCustomTitleCom;
echo $tkTitleCom; // will be default or custom

(2) 打印

试试这个而不是if ... else; (括号)内的表达式称为 a ternary operator,第 2 行中的表达式是 a 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

于 2013-04-16T00:16:03.990 回答
1

您可以在 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");
于 2013-04-16T00:22:47.780 回答
1

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_* (已弃用)。

我认为这应该可以解决问题。

于 2013-04-16T00:37:44.610 回答