我在尝试找出目前需要的查询时遇到了一些困难。
我会尽力解释这种情况并尽可能缩短。
我有一个名为articles_properties的多对多表,它来自其他两个表的组合:文章和属性。这些表具有以下结构,包含最重要的列以及一些示例:
Property table
-------------------------
| id | property_name|
| 1 | name |
| 2 | variations |
-------------------------
Article table
--------------
| id |
| A1 |
| A2 |
| A3 |
| A4 |
| A5 |
--------------
Article_properties table
--------------------------------------------------
| article_id | property_id | property_value |
| A1 | 1 | Pencil |
| A1 | 2 | A2, A3 |
| A2 | 1 | Pencil (blue) |
| A3 | 1 | Pencil (green) |
| A4 | 1 | Book |
| A5 | 1 | Tennis ball |
--------------------------------------------------
基本上你可以看到。也许唯一看起来不直观的是变体:它是确定文章不同变体的属性。例如,文章铅笔有两个变体:铅笔(蓝色)和铅笔(绿色),在列property_value中用它们各自的文章ID表示。
现在问题是我想从Article_properties表中获取所有文章,除了出现在另一个文章的属性变体中的文章。这意味着我希望获得如下结果:
Query result
--------------------------------------------------
| article_id | property_id | property_value |
| A1 | 1 | Pencil |
| A1 | 2 | A2, A3 |
| A4 | 1 | Book |
| A5 | 1 | Tennis ball |
--------------------------------------------------
如何在保持尽可能简单和干净的同时做到这一点?目前我有以下查询,该查询无法按预期工作:
SELECT ap.* FROM article_properties ap
LEFT JOIN property p ON p.id = ap.property_id
WHERE (p.property_name = 'name' OR p.property_name = 'variations')
AND ap.property_value != ''
AND ap.property_value NOT LIKE CONCAT('%',ap.article_id,'%')
GROUP BY ap.article_id, ap.property_id
我的错误是什么,或者我错过了什么?
感谢您抽出宝贵时间回答。
答案 0 :(得分:1)
我对MySQL工作很多..但问题似乎很有趣所以我试图用T-SQL来解决它......这就是我在T-SQL中如何做到的...如果你能把它翻译成MySQL ,希望它能帮到你。
无论如何这就是我所做的
只需在此设置数据,与您的输入相同
If object_id('tempdb..#temp') is not null drop table #temp
create table #Temp (ID int, descriptions nvarchar(100))
insert into #Temp (ID, descriptions) values (2, 'A2, A3'),
(1, 'Pencil (blue)'),
(1, 'Pencil (green)'),
(1, 'Book'),
(1, 'Tennis ball'),
(1, 'Pencil')
创建tempTables,row_number仅用于while循环并按'description desc'排序..那样'Pencil(绿色)'在'Pencil'之前出现
If object_id('tempdb..#tempWithRowNum') is not null drop table #tempWithRowNum
select row_number() over (order by descriptions desc) rownum,
* into #tempWithRowNum from #temp t1
If object_id('tempdb..#Finish') is not null drop table #Finish
create table #Finish (LastStanding_property nvarchar(100))
为while循环获取Max并设置变量
declare @s int = (select max(rownum) from (
select row_number() over (order by descriptions desc) rownum,
* from #temp t1)
src)
declare @Thing nvarchar(100)
declare @cmd nvarchar(max)
declare @Count int
declare @ParmDefinition nvarchar(100)
declare @i int = 1
这是逻辑...我只是使用一个描述运行整个表,如果我得到count(*)高于1,这意味着你有一些property_value类似
while @i <= @s
begin
set @Thing = (select descriptions from #tempWithRowNum where rownum = @i)
set @cmd = 'select @retvalOut = count(*)
from #temp where descriptions like ''%' + @Thing + '%'''
SET @ParmDefinition = N'@retvalOUT int OUTPUT';
EXEC sp_executesql @cmd, @ParmDefinition, @retvalOUT=@Count OUTPUT;
IF @Count = 1
begin
insert into #Finish (LastStanding_property) values (@Thing)
end
else
begin
set @cmd = 'delete from #Finish where LastStanding_property like ''%' + @Thing + '%'''
execute (@cmd)
insert into #Finish (LastStanding_property) values (@Thing)
end
set @i = @i + 1
end
select * from #Finish
所以,就像我说的..如果你得到Count(*)高于1 ...意味着你有“Child”属性值...你从#Finish表中删除它们并插入“parent”值然后你得到你想要什么