如何编写多层查询?

时间:2018-08-13 13:59:40

标签: sql database

我有一个物品清单。我正在尝试从中提取特定子集。

表中所有匹配的条目:

已在varereg.variantav中输入。

在varereg.varenr中具有与varereg.variantav中的条目匹配的条目。

varereg.variantav指varereg.varenr中的其他项目。

我得到了所有在varereg.variantav中有价值的商品。通过使用:

Where 
varereg.variantav IS NOT NULL and 
varereg.variantav not like '';

但是我也想使用存储在varereg.variantav中的值从varereg.varenr中提取更多项目。

Where 
varereg.variantav in (  select 
variantav 
from 
varereg group by variantav having count(*) >=1);

不幸的是,我对SQL的组合还不够好。有什么建议吗?

这是我得到的最好的结果。

select 
varereg.varenr as                            Vare_nr,
varereg.varenavn as                          Vare_navn,
varereg.hovedgrp as                          Hovedg_nr,
vkat.katnavn as                              Hovedg_navn,
varereg.undergrp as                          Underg_nr,
vunderkat.ukatnavn as                        Underg_navn,
varereg.aktivvare as                         Aktiv,
varereg.webaktiv as                          Web_Aktiv,
varereg.Tilbud as                            Tilbud,
ISNULL(varemultikat.webshopvaregruppe, 0) as Multi_Aktiv,
ISNULL(vkat2.hovedgrp, 0) as                 Multi_Hovedg_nr,
ISNULL(vkat2.katnavn, '0') as                Multi_Hovedg_navn,
ISNULL(vunderkat2.Undergrp, 0) as            Multi_Underg_nr,
ISNULL(vunderkat2.ukatnavn, '0') as          Multi_Underg_navn,
varereg.id as                                Vare_ID,
vkat.id as                                   Hovedg_ID,
vunderkat.id as                              Underg_ID,
varereg.variantav


From 
varereg 
left outer join vkat on                    varereg.vkatid=vkat.id 
left outer join vunderkat on               varereg.vunderkatid=vunderkat.id
left outer join varemultikat on            varereg.id=varemultikat.vareid
left outer join vkat as vkat2 on           varemultikat.vkatid=vkat2.id 
left outer join vunderkat as vunderkat2 on varemultikat.vunderkatid=vunderkat2.id 

Where 
varereg.variantav IS NOT NULL and 
varereg.variantav not like '' and 
varereg.variantav like '996618-MAL' or
varereg.varenr like '996618-MAL'
;

shows the result of query in the text placed above this image.

 and 
varereg.variantav like '996618-MAL' or
varereg.varenr like '996618-MAL'
在查询中放置

以限制搜索并激发所需的结果。如图所示。


当我解释我的需要时,我当然还不够清楚。

在这里澄清我要说的话:

SELECT
    v.varenr AS Vare_nr,
    v.varenavn AS Vare_navn,
    v.hovedgrp AS Hovedg_nr,
    vk.katnavn AS Hovedg_navn,
    v.undergrp AS Underg_nr,
    vuk.ukatnavn AS Underg_navn,
    v.aktivvare AS Aktiv,
    v.webaktiv AS Web_Aktiv,
    v.Tilbud AS Tilbud,
    ISNULL(vm.webshopvaregruppe, 0) AS Multi_Aktiv,
    ISNULL(vk2.hovedgrp, 0) AS Multi_Hovedg_nr,
    ISNULL(vk2.katnavn, '0') AS Multi_Hovedg_navn,
    ISNULL(vuk2.Undergrp, 0) AS Multi_Underg_nr,
    ISNULL(vuk2.ukatnavn, '0') AS Multi_Underg_navn,
    v.id AS Vare_ID,
    vk.id AS Hovedg_ID,
    vuk.id AS Underg_ID,
    v.variantav
FROM 
    varereg v

    LEFT JOIN vkat vk ON v.vkatid = vk.id 
    LEFT JOIN vunderkat vuk ON v.vunderkatid = vuk.id
    LEFT JOIN varemultikat vm ON v.id = vm.vareid
    LEFT JOIN vkat vk2 ON vm.vkatid = vk2.id 
    LEFT JOIN vunderkat vuk2 ON v.vunderkatid = vuk2.id 
WHERE 
    v.variantav IS NOT NULL
    AND v.variantav <> ''

上面的代码工作正常。但我需要更多连接到同一查询

我希望将此结果链接到查询末尾。

WHERE 
    (v.variantav IS NOT NULL
    AND v.variantav <> '') OR 

v.varenr like (

select 
variantav

from 
varereg 
group by variantav
having count(*) >=1

)

1 个答案:

答案 0 :(得分:0)

尝试一下。我不得不重构一下您的查询,因为样式困扰了我:D

SELECT
    v.varenr AS Vare_nr,
    v.varenavn AS Vare_navn,
    v.hovedgrp AS Hovedg_nr,
    vk.katnavn AS Hovedg_navn,
    v.undergrp AS Underg_nr,
    vuk.ukatnavn AS Underg_navn,
    v.aktivvare AS Aktiv,
    v.webaktiv AS Web_Aktiv,
    v.Tilbud AS Tilbud,
    ISNULL(vm.webshopvaregruppe, 0) AS Multi_Aktiv,
    ISNULL(vk2.hovedgrp, 0) AS Multi_Hovedg_nr,
    ISNULL(vk2.katnavn, '0') AS Multi_Hovedg_navn,
    ISNULL(vuk2.Undergrp, 0) AS Multi_Underg_nr,
    ISNULL(vuk2.ukatnavn, '0') AS Multi_Underg_navn,
    v.id AS Vare_ID,
    vk.id AS Hovedg_ID,
    vuk.id AS Underg_ID,
    v.variantav
FROM 
    varereg v
    INNER JOIN (SELECT variantav FROM varereg GROUP BY variantav HAVING COUNT(*) >= 1) x ON x.variantav = v.variantav
    LEFT JOIN vkat vk ON v.vkatid = vkat.id 
    LEFT JOIN vunderkat vuk ON v.vunderkatid = vuk.id
    LEFT JOIN varemultikat vm ON v.id = vm.vareid
    LEFT JOIN vkat vk2 ON vm.vkatid = vk2.id 
    LEFT JOIN vunderkat vuk2 ON v.vunderkatid = vuk2.id 
WHERE 
    v.variantav IS NOT NULL
    AND v.variantav <> '';

键是x的INNER JOIN,因为这会添加您要求的逻辑。我不太确定为什么要限制为单个variantav,所以我认为这是出于测试目的,可以忽略吗?


好的,我完全误解了您出现的问题。恐怕我已经重读了几次,但仍然听不懂。

您说过要执行以下所有操作的查询。

表中所有匹配的条目:

  • 已在varereg.variantav中输入。
  • 在varereg.varenr中具有与varereg.variantav中的条目匹配的条目。
  • varereg.variantav指varereg.varenr中的其他项目。

因此,第一部分似乎还不错,您希望商品在产品表中具有variantav的条目(不确定如何翻译)。您的解决方案是检查NULL以及空字符串,同时拒绝这两个字符串。

您也可以使用ISNULL(variantav, '') <> ''执行此操作。优点是不引入逻辑运算符(ANDOR),这使事情变得更简单。

下一点是我要失去它的地方。您是否只是在说要接受NULL中什么都没有(或variantav)但varenr中有些东西的行?还是您是说,varenr中的值与表中至少另一行的variantav中的值相匹配才可以接受?

我不知道您的“查找具有多个实例(即重复项)的项目”查询与此有何关系。

由于LEFT JOIN都只是“颤抖”,因此整个查询可以大大简化,并且可以将其取出,然后在有工作的时候重新添加。

因此您的原始查询变为:

SELECT
    v.variantav,
    v.varenr
FROM 
    varereg v
WHERE 
    --ISNULL(v.variantav, '') <> '' (unnecessary with explicit value defined)
    v.variantav = '996618-MAL' 
    OR v.varenr = '996618-MAL';

如果您想要我所知道的想要的(但我<50%的自信这实际上就是您现在想要的),那么您可以执行以下操作:

SELECT
    v.variantav,
    v.varenr
FROM 
    varereg v
WHERE 
    ISNULL(v.variantav, '') <> ''
    OR EXISTS (SELECT * FROM varereg v2 WHERE v2.variantav = v.varenr);

我要靠近吗?


啊哈,我们都同时编辑了!

我认为您只需添加以下逻辑即可:

SELECT
    v.variantav,
    v.varenr
FROM 
    varereg v
    LEFT JOIN (SELECT variantav FROM varereg GROUP BY variantav HAVING COUNT(*) > 1) x ON x.variantav = v.varenr
WHERE 
    ISNULL(v.variantav, '') <> ''
    OR x.variantav IS NOT NULL;

那不是您的整个查询,因此只需添加所有其他SELECT列和LEFT JOIN即可,您应该很好吗?