连接4个表并分配默认行

如何解决连接4个表并分配默认行

我有以下4张桌子:

商店:

id     |    name
------------------
1         Store 1
2         Store 2
3         Store 3
4         Store 4
5         Store 5
6         Store 6

ITEM_TYPES:

type   |  description
----------------------
*A           *All (Automatically all stores would have this item) 
*SP          *Store_Specfic (Only a specific store would have this item)
T            Toys
H            Home
P            Pet

STORES_ITEM_TYPES:

STORE_ID   |  ITEM_TYPE
------------------------
1                T
1                P
3                T
5                T
5                H
5                P

项目:

ITEM_NAME           |       SPECIFIC_STORE_ID       |   ITEM_TYPE
--------------------------------------------------------------------
CAT                            NULL                       P
BROOM                          NULL                       H
LEGO                           NULL                       T
BATTERY                        NULL                       *A
GIFT CARD                      NULL                       *A
PARROT                         NULL                       P
STORE2 ONLY ITEM                2                         *SP

我想输出每个商店的所有商品:

STORE_NAME    |  ITEM_NAME     |      ITEM_TYPE    
-------------------------------------------------
STORE1              BATTERY              *A
STORE1              GIFT CARD            *A
STORE1              LEGO                 *T
STORE1              CAT                  *P
STORE1              PARROT               *P

STORE2              BATTERY              *A
STORE2              GIFT CARD            *A
STORE2              STORE2 ONLY ITEM     *SP

STORE3              BATTERY              *A
STORE3              GIFT CARD            *A
STORE3              LEGO                 *T

STORE4              BATTERY              *A
STORE4              GIFT CARD            *A

STORE5              BATTERY              *A
STORE5              GIFT CARD            *A
STORE5              CAT                  *P
STORE5              PARROT               *P
STORE5              BROOM                *H

STORE6              BATTERY              *A
STORE6              GIFT CARD            *A

那是怎么回事?我有一些商店。我有一些东西。这些项目具有类型。例如,LEGO是具有玩具类型的物品。有些项目具有“特殊”类型。这些前缀为“ *”。 *A类型代表“全部”。这意味着该商品应在每个单独的商店中。还有一种*SP类型,表示该商品应仅在一个特定的商店中,并且该商店在ITEMS表中指明。

我要执行的查询是显示每个商店拥有的所有商品。

我面临的问题是STORES_ITEM_TYPES表未指定特殊类型(* A和* SP)。这是因为假定这些类型已经固有地已经成为所有商店的一部分,所以不需要指定它们(这不是我的数据模型)。​​

我尝试了以下查询:

SELECT * 
FROM   stores p,stores_item_types t,items r,item_types y 
WHERE  stores.store_id = stores_item_types.store_id 
       AND stores_item_types.item_type = items.item_type 
       AND stores_item_types.item_type = item_types.item_type

除了特殊项目(* A和* SP)之外,我正在获取所有项目。所以我的输出目前是这样的:

STORE_NAME    |  ITEM_NAME     |      ITEM_TYPE    
-------------------------------------------------
STORE1              LEGO                 *T
STORE1              CAT                  *P
STORE1              PARROT               *P

STORE3              LEGO                 *T

STORE5              CAT                  *P
STORE5              PARROT               *P
STORE5              BROOM                *H

这是一个sqlfiddle: sqlfiddle.com/#!9/cae02d/1

解决方法

注意:此答案的先前版本尝试(相当笨拙)解决了异常数据模型的局限性。我认为以下是一种更好,更清晰的方法。

这里的主要问题是数据没有完全标准化,特别是关于商店和商品类型之间的关联。我的建议是使用两个子查询来获得更清晰的stores_item_typesitems版本,然后制作简单的INNER JOIN

让我们从stores_item_types开始。我们希望派生表明确表示每个商店也都携带*A类型,并且每个商店还都拥有自己的 *SP类型。例如:

SELECT *
FROM stores_item_types sit
UNION
SELECT store_id,'*A'
FROM stores
UNION
SELECT store_id,CONCAT('*SP',store_id)
FROM stores

会产生这样的东西:

STORE_ID    ITEM_TYPE
1           *A
1           *SP1
1           P
1           T
2           *A
2           *SP2
3           *A
3           *SP3
...         ...

,依此类推。我们还需要items的派生版本,以匹配新类型*SP1*SP2等。

SELECT
  item_name,specific_store_id,CONCAT(item_type,IFNULL(specific_store_id,'')) item_type
FROM items

然后,最终查询将如下所示:

SELECT
  s.name store_name,i.item_name,i.item_type
FROM stores s
INNER JOIN (
  SELECT *
  FROM stores_item_types sit
  UNION
  SELECT store_id,'*A'
  FROM stores
  UNION
  SELECT store_id,store_id)
  FROM stores ORDER BY store_id,item_type
) sit ON s.store_id = sit.store_id
INNER JOIN (
  SELECT
    item_name,'')) item_type
  FROM items
) i ON i.item_type = sit.item_type
ORDER BY s.store_id,sit.item_type

您可以在this fiddle中看到此查询的运行情况。

,

您能检查一下是否符合您的期望

我已经使用union all来区分3个不同的item_types

第一个联合: :针对那些我们在stores_item_types中匹配了商品并排除了*A*SP之类的商品的人。 / p>

第二个联合: item_type = '*A',并使用所有可用的商店ID进行交叉联接。

第三联盟: item_type='*SP',并与商店ID一起加入以包括到特定商店。

select *
  from
(
-- for all matched items in store_item_types
select st.id,st.name,it.item_name,it.item_type
  from stores st
  join stores_item_types sit
    on st.id = sit.store_id 
   and sit.item_type not in ('*A','*SP')
  join items it
    on sit.item_type = it.item_type
  join item_types ity
    on sit.item_type = ity.type
union all
-- item type *A for all stores 
select st.id,it.item_type
  from stores st
  cross join items it
     on it.item_type = '*A'
union all
-- specific items for specific store
select st.id,it.item_type
  from stores st
  join items it
    on it.specific_store_id = st.id
where it.item_type = '*SP'
) a
order by id,case item_type
              when '*A' then 1
              when 'H' then 2
              when 'P' then 3
              when 'T' then 4
              when '*SP' then 5
              else 6
            end;

注意:为方便起见,我下了额外的订单以查看可以删除的输出。而且我只选择了根据预期输出所必需的列,并且可以根据需要添加其他列。

Db<>fiddle供参考

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-