- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在努力解决以下情况:
第一种方法:
SELECT * FROM vinyl_tracks vt
INNER JOIN vinyl_keys vk ON vt.mKeyID = vk.mKeyID
INNER JOIN vinyl_tracks_styles vts ON vt.trackID = vts.trackID
INNER JOIN vinyl_styles vs ON vts.styleID = vs.styleID
WHERE vinylID = :vinylID
对于某些轨道,表vts
将包含两种或多种样式(该表仅包含位于不同行的trackID
和styleID
。这会导致整个结果重复。我尝试过 DISTINCT
和各种 GROUP BY
,包括 DISTINCT
和 GROUP BY
。这确实会为每个轨道返回一个结果,但缺少第二个 styleID
。
这是此查询的 var_dump
,没有任何 GROUP BY
:
array (size=4)
0 =>
array (size=10)
'trackID' => string '868' (length=3)
'vinylID' => string '249' (length=3)
'side' => string 'A' (length=1)
'trackArtist' => string '' (length=0)
'trackTitle' => string 'Waiting (John Creamer & Stephane K Remix)' (length=41)
'notes' => string '130 bpm' (length=7)
'mKeyID' => string '1' (length=1)
'mKey' => string 'A major' (length=7)
'Camelot' => string '11B' (length=3)
'styleID' => string '8' (length=1)
1 =>
array (size=10)
'trackID' => string '868' (length=3)
'vinylID' => string '249' (length=3)
'side' => string 'A' (length=1)
'trackArtist' => string '' (length=0)
'trackTitle' => string 'Waiting (John Creamer & Stephane K Remix)' (length=41)
'notes' => string '130 bpm' (length=7)
'mKeyID' => string '1' (length=1)
'mKey' => string 'A major' (length=7)
'Camelot' => string '11B' (length=3)
'styleID' => string '17' (length=2)
2 =>
array (size=10)
'trackID' => string '869' (length=3)
'vinylID' => string '249' (length=3)
'side' => string 'B' (length=1)
'trackArtist' => string '' (length=0)
'trackTitle' => string 'Waiting (Jay Welsh (Black Ice) Remix)' (length=37)
'notes' => string '135 bpm' (length=7)
'mKeyID' => string '1' (length=1)
'mKey' => string 'A major' (length=7)
'Camelot' => string '11B' (length=3)
'styleID' => string '17' (length=2)
3 =>
array (size=10)
'trackID' => string '869' (length=3)
'vinylID' => string '249' (length=3)
'side' => string 'B' (length=1)
'trackArtist' => string '' (length=0)
'trackTitle' => string 'Waiting (Jay Welsh (Black Ice) Remix)' (length=37)
'notes' => string '135 bpm' (length=7)
'mKeyID' => string '1' (length=1)
'mKey' => string 'A major' (length=7)
'Camelot' => string '11B' (length=3)
'styleID' => string '8' (length=1)
然后我运行另一个查询来获取所有样式,以便我可以填充多个选择下拉列表。这就是使用 foreach
循环创建下拉列表和屏幕截图的样子 - 两个轨道,每个轨道都有两种样式,显示为四个轨道:
$allStylesQuery = $db->prepare("SELECT * FROM vinyl_styles ORDER BY styleID ASC");
$allStylesQuery->execute();
$styles = $allStylesQuery->fetchAll(PDO::FETCH_ASSOC);
$stylesSelector = "<select multiple=\"multiple\" class=\"form-control form-control-sm stylesSelector\" name=\"styleID[".$trow['trackID']."][]\"><option> – </option>";
foreach($styles as $style) {
if(isset($trow['styleID']) && ($trow['styleID'] == $style['styleID'])) {
$stylesSelector .= "<option selected=\"selected\" value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
else {
$stylesSelector .= "<option value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
}
$stylesSelector .= "</select>";
替代方法:我还尝试使用两个查询来完成相同的任务:
SELECT * FROM vinyl_tracks vt
INNER JOIN vinyl_keys vk ON vt.mKeyID = vk.mKeyID
WHERE vinylID = :vinylID
然后,在 foreach
循环内获取第一个查询的结果,以下查询:
SELECT * FROM vinyl_tracks_styles vts
RIGHT JOIN vinyl_styles vs ON vts.styleID = vs.styleID
WHERE vts.trackID = :trackID
这种替代方法可以产生我想要的结果,例如:
array (size=2)
0 =>
array (size=3)
'trackID' => string '868' (length=3)
'styleID' => string '8' (length=1)
'styleName' => string 'progressive house' (length=17)
1 =>
array (size=3)
'trackID' => string '868' (length=3)
'styleID' => string '17' (length=2)
'styleName' => string 'progressive trance' (length=18)
为了在选择下拉列表中列出所有可能的样式,我需要再运行一个查询(上面的 WHERE
条件会阻止显示所有样式名称和 ID,尽管 RIGHT JOIN
,我知道):
SELECT * FROM vinyl_styles ORDER BY styleID ASC
突出显示我发现的选择选项(样式)的唯一方法是将两个 foreach
循环嵌套在另一个循环中,这当然会再次导致重复的结果:
$trackStylesQuery = $db->prepare("SELECT * FROM vinyl_tracks_styles vts
RIGHT JOIN vinyl_styles vs ON vts.styleID = vs.styleID
WHERE vts.trackID = :trackID");
$trackStylesQuery->bindParam(':trackID', $trow['trackID'], PDO::PARAM_INT);
$trackStylesQuery->execute();
$trackStyles = $trackStylesQuery->fetchAll(PDO::FETCH_ASSOC);
//var_dump($trackStyles);
$allStylesQuery = $db->prepare("SELECT * FROM vinyl_styles ORDER BY styleID ASC");
$allStylesQuery->execute();
$styles = $allStylesQuery->fetchAll(PDO::FETCH_ASSOC);
$stylesSelector = "<select multiple=\"multiple\" class=\"form-control form-control-sm stylesSelector\" name=\"styleID[".$trow['trackID']."][]\"><option> – </option>";
foreach($styles as $style) {
foreach($trackStyles as $trackStyle) {
if(isset($trackStyle['styleID']) && ($trackStyle['styleID'] == $style['styleID'])) {
$stylesSelector .= "<option selected=\"selected\" value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
else {
$stylesSelector .= "<option value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
}
}
$stylesSelector .= "</select>";
如果我坚持上面的第一个单查询变体,整行输入将重复两次,因此对于这两个轨道,我得到四行。
我真的没有主意,请帮忙。
更新
采用@Ultimater建议的更少查询方法,我现在已经拥有了所需的所有详细信息,唯一的问题是样式列表在样式下拉列表中为跟踪的每种样式重复有。如果轨道仅添加一种样式或未添加任何样式,则没有问题。下面发布我的完整代码:
$tracksQuery = $db->prepare("SELECT vt.trackID, vt.vinylID, vt.side, vt.trackArtist, vt.trackTitle, vt.notes, vt.mKeyID, vk.mKey, vk.Camelot,
GROUP_CONCAT(vts.styleID SEPARATOR ',') AS 'styleIDs',
GROUP_CONCAT(vs.styleName SEPARATOR ',') AS 'styleNames'
FROM vinyl_tracks vt
INNER JOIN vinyl_keys vk ON vt.mKeyID = vk.mKeyID
LEFT JOIN vinyl_tracks_styles vts ON vt.trackID = vts.trackID
LEFT JOIN vinyl_styles vs ON vts.styleID = vs.styleID
WHERE vt.vinylID = :vinylID
GROUP BY vt.trackID");
$tracksQuery->bindParam(':vinylID', $vinylID);
$tracksQuery->execute();
$tracks = $tracksQuery->fetchAll(\PDO::FETCH_ASSOC);
//var_dump($tracks);
// fetch all styles to use in the dropdown
$allStylesQuery = $db->prepare("SELECT * FROM vinyl_styles ORDER BY styleID ASC");
$allStylesQuery->execute();
$styles = $allStylesQuery->fetchAll(PDO::FETCH_ASSOC);
// build a dropdown menu for each of the tracks
// which contains all styles and where the current track's styles are selected
$stylesSelector = "";
foreach($tracks as $track) {
// start building the selector
$stylesSelector .= "<select multiple=\"multiple\" class=\"form-control form-control-sm\" name=\"styleID[".$track['trackID']."][]\"><option> – </option>";
// check if any styles have been added for this track
if(!empty($track['styleIDs'])) {
// check if StyleIDs and StyleNames results contain a comma
// which means more than one style has been added for that track
if((strpos($track['styleIDs'], ',')) && (strpos($track['styleNames'], ','))) {
// separate trackStyleIDs and trackStyleNames
$trackStyleIDs = explode(',', $track['styleIDs']);
$trackStyleNames = explode(',', $track['styleNames']);
// now combine them in one array where styleID is the key and styleName is the value
$styleIDs_and_Names = array_combine($trackStyleIDs, $trackStyleNames);
// for each of the styleID => styleName pairs in the array
// check against all available styles if selected
foreach($styleIDs_and_Names as $styleID => $styleName) {
// iterate over all available styles
foreach($styles as $style) {
// if there's a match, add "selected" to the option
if($styleID == $style['styleID']) {
$stylesSelector .= "<option selected=\"selected\" value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
else {
$stylesSelector .= "<option value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
}
}
}
// only one style has been added for this track
else {
// iterate over all available styles
foreach($styles as $style) {
// if there's a match, add "selected" to the option
if($track['styleIDs'] == $style['styleID']) {
$stylesSelector .= "<option selected=\"selected\" value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
else {
$stylesSelector .= "<option value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
}
}
}
// if no styles have been added for this track
else {
// iterate all available styles
foreach($styles as $style) {
$stylesSelector .= "<option value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
}
$stylesSelector .= "</select>";
}
最佳答案
您可以使用 GROUP_CONCAT将结果缩小到二维,这样您就不会仅仅为了填充样式下拉列表而获得重复的相册。相反,您可以将样式组合起来并使用换行符使其变得漂亮。
您的查询最终看起来像这样:
SELECT
trackID,
vinylID,
side,
trackArtist,
trackTitle,
notes,
GROUP_CONCAT(mKeyID SEPARATOR '\n') as 'mKeyIDs',
GROUP_CONCAT(mKey SEPARATOR '\n') as 'mKeys',
Camelot,
GROUP_CONCAT(styleID SEPARATOR '\n') AS 'styleIDs',
GROUP_CONCAT(styleName SEPARATOR '\n') AS 'styleNames'
FROM
vinyl_tracks vt
INNER JOIN
vinyl_keys vk ON vt.mKeyID = vk.mKeyID
INNER JOIN
vinyl_tracks_styles vts ON vt.trackID = vts.trackID
INNER JOIN
vinyl_styles vs ON vts.styleID = vs.styleID
GROUP BY
vt.trackID
WHERE
vinylID = :vinylID
我在这里按轨道 ID 进行分组,因为这似乎是您用来确定某些内容是否重复的标准。从那里,我使用 GROUP_CONCAT 和新的行分隔符来在同一单元格中显示受该组影响的所有样式。您的 PHP 可以引用此单元格,并在新行字符上展开以获取填充下拉列表所需的内容。
首先确保此查询直接在数据库上运行,看看是否需要对其进行调整。
或者,如果您的 MySQL 版本支持 JSON_ARRAYAGG ,您可以使用它代替 GROUP_CONCAT 来完成功能等效的行为,尽管更简洁:
SELECT
trackID,
vinylID,
side,
trackArtist,
trackTitle,
notes,
JSON_ARRAYAGG(mKeyID) AS 'mKeyIDs',
JSON_ARRAYAGG(mKey) AS 'mKeys',
Camelot,
JSON_ARRAYAGG(styleID) AS 'styleIDs',
JSON_ARRAYAGG(styleName) AS 'styleNames'
FROM
vinyl_tracks vt
INNER JOIN
vinyl_keys vk ON vt.mKeyID = vk.mKeyID
INNER JOIN
vinyl_tracks_styles vts ON vt.trackID = vts.trackID
INNER JOIN
vinyl_styles vs ON vts.styleID = vs.styleID
GROUP BY
vt.trackID
WHERE
vinylID = :vinylID
然后在 PHP 中,您只需引用 $row['styleIDs']
和 $row['styleNames']
即可生成 key=>value 对“样式”下拉列表中使用的每个选项。
对于音乐“Keys”下拉选项,您可以引用 $row['mKeyID']
和 $row['mKeys']
来生成 key= >“键”下拉列表中使用的每个选项的值对。
更新:
我在本地进行了设置,并查看了 OP 遇到的问题。我的查询没问题。然而,当尝试显示下拉菜单时,OP 的 PHP 循环逻辑遇到了错误。更具体地说,以下逻辑是错误的:
foreach($styles as $style) {
// if there's a match, add "selected" to the option
if($track['styleIDs'] == $style['styleID']) {
$stylesSelector .= "<option selected=\"selected\" value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
else {
$stylesSelector .= "<option value=\"".$style['styleID']."\">".$style['styleName']."</option>";
}
}
}
现在我明白了 OP 想要做什么,让我们重写整个困惑的内容。我已经重构了代码。我也在本地测试过:
$tracksQuery = $db->prepare("SELECT vt.trackID, vt.vinylID, vt.side, vt.trackArtist, vt.trackTitle, vt.notes, vt.mKeyID, vk.mKey, vk.Camelot,
GROUP_CONCAT(vts.styleID SEPARATOR ',') AS 'styleIDs'
FROM vinyl_tracks vt
INNER JOIN vinyl_keys vk ON vt.mKeyID = vk.mKeyID
LEFT JOIN vinyl_tracks_styles vts ON vt.trackID = vts.trackID
WHERE vt.vinylID = :vinylID
GROUP BY vt.trackID");
$tracksQuery->bindParam(':vinylID', $vinylID);
$tracksQuery->execute();
$tracks = $tracksQuery->fetchAll(\PDO::FETCH_ASSOC);
$allStylesQuery = $db->prepare("SELECT * FROM vinyl_styles ORDER BY styleID ASC");
$allStylesQuery->execute();
$styles = $allStylesQuery->fetchAll(PDO::FETCH_ASSOC);
$stylesSelector = "";
foreach($tracks as $track)
{
$stylesSelector .= "<select multiple=\"multiple\" class=\"form-control form-control-sm\" name=\"styleID[".$track['trackID']."][]\"><option> – </option>";
$trackStyleIDs = explode(',', $track['styleIDs']);
foreach($styles as $style)
{
$optionValue = $style['styleID'];
$optionText = $style['styleName'];
$optionSelected = in_array($optionValue, $trackStyleIDs) ? ' selected="selected"' : '';
$stylesSelector .= sprintf('<option value="%s"%s>%s</option>', $optionValue,$optionSelected,$optionText);
}
$stylesSelector .= "</select>";
}
关于php - MySQL + PHP : Avoid duplicate result due to two results from joined table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55932825/
我有一个内部表,里面有 108 个条目。从 9 到 9 个条目重复条目,我想删除这些重复项。由于它们完全相同,我使用了 delete adjacent duplicates from itab com
在 Team Foundation Server (TFS) 中链接两个工作项 (WI) 时,在什么情况下将“Duplicate”和“Duplicate Of”区分为“链接类型”是有意义的? 如何处理
ld: duplicate symbol _velocityX in \ /Users/Student/Library/Developer/Xcode/DerivedData/finalproject
我使用 PHP 和 Mysql。 此 SQL 有效: INSERT INTO products (id, title, description) VALUES (10, 'va
我有一个大数据框 (120000x40),我尝试在每一行中找到重复项并显示它们。这就是我的尝试: 创建数据框 import pandas as pd df = pd.DataFrame({'col1'
我是 mySQL 和 PHP 的新手,请多多包涵。 如果我的查询有重复字段,我该如何做到这一点,检索到的数据将具有重复查询字段的重复数据。 一个例子是这样的: 查询 id = 34, 54, 21,
我一直遇到这个错误,但我无法理解它,因为它提示一个值恰好出现一次。 Exception in thread "main" java.lang.IllegalStateException: Duplic
我有一个带有 Vuejs 和 Laravel 的 Web 应用程序 我想使用 CKEditor 5 我安装了依赖项 npm install --save @ckeditor/ckeditor5-vue
我有一个包含以下数据的 csv 文件: Id,Name,Type,date 1,name1,employee,25/04/2017 2,name2,contrator,26/04/2017 3,nam
import CKEditor from '@ckeditor/ckeditor5-react'; import ClassicEditor from '@ckeditor/ckeditor5-bui
表定义: CREATE TABLE PositionalDataNGS ( Date DATE, Time TIME(3) , X FLOAT(5), Y FLOAT(5), D FLOAT(5) ,
我目前正在做一个项目,我要处理数以千计的数据包。现在,我记录每个数据包的 IP 和 MAC 地址以及一些其他信息。为了存储所有这些,我使用 MySQL 并且我的脚本是用 Node.js 编写的。目前我
I am using MySQL 5.1.56, MyISAM. My table looks like this:我使用的是MySQL 5.1.56,MyISAM。我的桌子是这样的: CR
我是新来的,对 SQL 比较陌生。我有一个类似这样的表: [Pk], [Case_No], [Status], [Open_Date], [Close_Date], [Case_Age], [Repo
为什么会收到此警告? warning No duplicate props allowed react/jsx-no-duplicate-props# 它显示的是第28行,但没有使用 Prop 。 最
是否有任何函数或方法可以在 python 2.7 中递归实现此目的? Input : ['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P']]
我正在分析 hadoop 中的数据。有一些重复条目,其中 A、B 列重复,而 C 列不同。我想要做的是仅识别 A、B 重复项,然后为每个重复项打印出 C 列的不同值。 示例数据: row, data
您好,感谢阅读并可能对我有所帮助 我的问题的简要说明: 我正在将数据从一个 Firebird 数据库复制到另一个(称为 V14),并且我正在使用 IBExpert 来执行此操作。这些表的名称相同并且具
我想制作一张很像下面的图片: 我想使用 seaborn 使图表看起来漂亮,并让我自己以后更容易使用 facetgrids(我有十个不同的数据集,我想在同一个图表中显示。) 我在 seaborn 中找到
我在两列“user_id”和“project_id”上有一个复合唯一键。 当我尝试对单行或多行运行 DELETE 查询时,出现错误。 ERROR 1062: 1062: Duplicate entry
我是一名优秀的程序员,十分优秀!