(202307)wonderful-sql:集合运算(task4)

文章提供了几个关于使用UNION操作在MySQL中处理数据的例子,包括查找不同表中售价高于500的商品,计算表的交集,找出每类商品售价最高的商品以及使用内连结和关联子查询的方法。这些练习展示了如何在数据库管理中进行复杂的数据筛选和分析。

教程链接:Datawhale - 一个热爱学习的社区

知识学习(随记)

  1. 从表的加减法中间的练习题可以看出,union不仅可以用于对两个表取并,也可以用于对同一个表的不同条件的筛选取并。
  2. 也可以用union测试数据的兼容性。
  3. mysql即使到了8.0,也还是有好些不支持的运算。

练习题

4.1 找出 product 和 product2 中售价高于 500 的商品的基本信息 

SELECT *
  FROM Product
WHERE sale_price > 500
 UNION ALL
SELECT *
  FROM Product2
WHERE sale_price > 500;

4.2 借助对称差的实现方式, 求product和product2的交集

SELECT *
FROM
(SELECT * 
FROM product
UNION
SELECT *
From product2) u
WHERE product_id NOT IN
(SELECT product_id
FROM product
WHERE product_id NOT IN (SELECT product_id FROM product2)
UNION
SELECT product_id
FROM product2
WHERE product_id NOT IN (SELECT product_id FROM product));

4.3 每类商品中售价最高的商品都在哪些商店有售 ?

SELECT sp.shop_id, sp.shop_name, sp.product_id, p.product_type
FROM shopproduct sp
INNER JOIN product p
ON sp.product_id = p.product_id
WHERE sp.product_id IN 
(SELECT product_id
FROM product p1
INNER JOIN (SELECT product_type, MAX(sale_price) as max_price
FROM product
GROUP BY product_type) p2
ON p1.product_type = p2.product_type AND p1.sale_price=p2.max_price);

4.4 分别使用内连结和关联子查询每一类商品中售价最高的商品

内连结查询

SELECT product_name, product_type, sale_price
FROM product AS P1
WHERE sale_price = (SELECT MAX(sale_price)
FROM product AS P2
WHERE P1.product_type = P2.product_type)

关键子查询 

SELECT P1.product_id, P1.product_name, P1.product_type, P1.sale_price, P1.max_price
FROM product AS P1
INNER JOIN (SELECT product_type, MAX(sale_price) AS max_price
FROM product
GROUP BY product_type) AS P2 ON P1.product_type = P2.product_type
WHERE P1.sale_price = P2.max_price

4.5 用关联子查询实现:在 product 表中,取出 product_id, product_name, sale_price, 并按照商品的售价从低到高进行排序、对售价进行累计求和。

SELECT product_id, product_name, sale_price,(SELECT SUM(sale_price)
FROM product p2 WHERE p2.sale_price <= p1.sale_price) AS cumulative_sum
FROM product p1
ORDER BY sale_price;

 

<template> <div class="main-layout"> <div class="body-layout"> <Sidebar /> <div class="crud-container"> <div class="welcome"> <!-- 公共头部 --> <HeaderBar :devices="devices" @search="handleSearch" @search-reset="handleSearchReset" /> <el-main style="padding: 20px; display: flex; flex-direction: column"> <div> <!-- 首页内容 --> <div class="add-device"> <div class="add-device-bg"> <div class="hellow-text" style="margin-top: 30px"> 你好,小智 </div> <div class="hellow-text"> 让我们度过 <div style="display: inline-block; color: #5778ff"> 美好的一天! </div> </div> <div class="hi-hint">Hello, Let's have a wonderful day!</div> <div class="add-device-btn"> <div class="left-add" @click="showAddDialog"> 添加智能体 </div> <div style=" width: 23px; height: 13px; background: #5778ff; margin-left: -10px; " /> <div class="right-add"> <i class="el-icon-right" @click="showAddDialog" style="font-size: 20px; color: #fff" /> </div> </div> </div> </div> <div class="device-list-container"> <template v-if="isLoading"> <div v-for="i in skeletonCount" :key="'skeleton-' + i" class="skeleton-item" > <div class="skeleton-image"></div> <div class="skeleton-content"> <div class="skeleton-line"></div> <div class="skeleton-line-short"></div> </div> </div> </template> <template v-else> <DeviceItem v-for="(item, index) in devices" :key="index" :device="item" @configure="goToRoleConfig" @deviceManage="handleDeviceManage" @delete="handleDeleteAgent" @chat-history="handleShowChatHistory" /> </template> </div> </div> <AddWisdomBodyDialog :visible.sync="addDeviceDialogVisible" @confirm="handleWisdomBodyAdded" /> </el-main> <el-footer> <version-footer /> </el-footer> <chat-history-dialog :visible.sync="showChatHistory" :agent-id="currentAgentId" :agent-name="currentAgentName" /> </div> </div> </div> </div> </template> <script> import Api from "@/apis/api"; import AddWisdomBodyDialog from "@/components/AddWisdomBodyDialog.vue"; import ChatHistoryDialog from "@/components/ChatHistoryDialog.vue"; import DeviceItem from "@/components/DeviceItem.vue"; import HeaderBar from "@/components/HeaderBar.vue"; import VersionFooter from "@/components/VersionFooter.vue"; import Sidebar from "@/components/SideBar.vue"; export default { name: "HomePage", components: { Sidebar, DeviceItem, AddWisdomBodyDialog, HeaderBar, VersionFooter, ChatHistoryDialog, }, data() { return { addDeviceDialogVisible: false, devices: [], originalDevices: [], isSearching: false, searchRegex: null, isLoading: true, skeletonCount: localStorage.getItem("skeletonCount") || 8, showChatHistory: false, currentAgentId: "", currentAgentName: "", }; }, mounted() { this.fetchAgentList(); }, methods: { showAddDialog() { this.addDeviceDialogVisible = true; }, goToRoleConfig() { // 点击配置角色后跳转到角色配置页 this.$router.push("/role-config"); }, handleWisdomBodyAdded(res) { this.fetchAgentList(); this.addDeviceDialogVisible = false; }, handleDeviceManage() { this.$router.push("/device-management"); }, handleSearch(regex) { this.isSearching = true; this.searchRegex = regex; this.applySearchFilter(); }, handleSearchReset() { this.isSearching = false; this.searchRegex = null; this.devices = [...this.originalDevices]; }, applySearchFilter() { if (!this.isSearching || !this.searchRegex) { this.devices = [...this.originalDevices]; return; } this.devices = this.originalDevices.filter((device) => { return this.searchRegex.test(device.agentName); }); }, // 搜索更新智能体列表 handleSearchResult(filteredList) { this.devices = filteredList; // 更新设备列表 }, // 获取智能体列表 fetchAgentList() { this.isLoading = true; Api.agent.getAgentList( ({ data }) => { if (data?.data) { this.originalDevices = data.data.map((item) => ({ ...item, agentId: item.id, })); // 动态设置骨架屏数量(可选) this.skeletonCount = Math.min( Math.max(this.originalDevices.length, 3), // 最少3个 10 // 最多10个 ); this.handleSearchReset(); } this.isLoading = false; }, (error) => { console.error("Failed to fetch agent list:", error); this.isLoading = false; } ); }, // 删除智能体 handleDeleteAgent(agentId) { this.$confirm("确定要删除该智能体吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { Api.agent.deleteAgent(agentId, (res) => { if (res.data.code === 0) { this.$message.success({ message: "删除成功", showClose: true, }); this.fetchAgentList(); // 刷新列表 } else { this.$message.error({ message: res.data.msg || "删除失败", showClose: true, }); } }); }) .catch(() => {}); }, handleShowChatHistory({ agentId, agentName }) { this.currentAgentId = agentId; this.currentAgentName = agentName; this.showChatHistory = true; }, }, }; </script> <style scoped> .main-layout { display: flex; flex-direction: column; height: 100vh; } .body-layout { display: flex; flex: 1; min-height: 0; } .crud-container { flex: 1; background: #f5f7fa; min-width: 0; min-height: 0; overflow: auto; } .welcome { min-width: 900px; min-height: 506px; height: 100vh; display: flex; flex-direction: column; background: linear-gradient(145deg, #e6eeff, #eff0ff); background-size: cover; /* 确保背景图像覆盖整个元素 */ background-position: center; /* 从顶部中心对齐 */ -webkit-background-size: cover; /* 兼容老版本WebKit浏览器 */ -o-background-size: cover; /* 兼容老版本Opera浏览器 */ } .add-device { height: 195px; border-radius: 15px; position: relative; overflow: hidden; background: linear-gradient( 269.62deg, #e0e6fd 0%, #cce7ff 49.69%, #d3d3fe 100% ); } .add-device-bg { width: 100%; height: 100%; text-align: left; background-image: url("@/assets/home/main-top-bg.png"); overflow: hidden; background-size: cover; /* 确保背景图像覆盖整个元素 */ background-position: center; /* 从顶部中心对齐 */ -webkit-background-size: cover; /* 兼容老版本WebKit浏览器 */ -o-background-size: cover; box-sizing: border-box; /* 兼容老版本Opera浏览器 */ .hellow-text { margin-left: 75px; color: #3d4566; font-size: 33px; font-weight: 700; letter-spacing: 0; } .hi-hint { font-weight: 400; font-size: 12px; text-align: left; color: #818cae; margin-left: 75px; margin-top: 5px; } } .add-device-btn { display: flex; align-items: center; margin-left: 75px; margin-top: 15px; cursor: pointer; .left-add { width: 105px; height: 34px; border-radius: 17px; background: #5778ff; color: #fff; font-size: 14px; font-weight: 500; text-align: center; line-height: 34px; } .right-add { width: 34px; height: 34px; border-radius: 50%; background: #5778ff; margin-left: -6px; display: flex; justify-content: center; align-items: center; } } .device-list-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); gap: 30px; padding: 30px 0; } /* 在 DeviceItem.vue 的样式中 */ .device-item { margin: 0 !important; /* 避免冲突 */ width: auto !important; } .footer { font-size: 12px; font-weight: 400; margin-top: auto; padding-top: 30px; color: #979db1; text-align: center; /* 居中显示 */ } /* 骨架屏动画 */ @keyframes shimmer { 100% { transform: translateX(100%); } } .skeleton-item { background: #fff; border-radius: 8px; padding: 20px; height: 120px; position: relative; overflow: hidden; margin-bottom: 20px; } .skeleton-image { width: 80px; height: 80px; background: #f0f2f5; border-radius: 4px; float: left; position: relative; overflow: hidden; } .skeleton-content { margin-left: 100px; } .skeleton-line { height: 16px; background: #f0f2f5; border-radius: 4px; margin-bottom: 12px; width: 70%; position: relative; overflow: hidden; } .skeleton-line-short { height: 12px; background: #f0f2f5; border-radius: 4px; width: 50%; } .skeleton-item::after { content: ""; position: absolute; top: 0; left: 0; width: 50%; height: 100%; background: linear-gradient( 90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0) ); animation: shimmer 1.5s infinite; } </style> 在代码不变的情况下实现懒加载
08-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早上真好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值