- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在寻找一个 SQL 查询,它可以将一组单独大小的项目映射到一组单独大小的设置桶。
我想满足以下条件:
举个例子,假设我的 bucket 和 items 表看起来像这样:
Bucket: Item:
+---------------------+ +---------------------+
| BucketID | Size | | ItemID | Size |
+---------------------+ +---------------------+
| 1 | 2 | | 1 | 2 |
| 2 | 2 | | 2 | 2 |
| 3 | 2 | | 3 | 5 |
| 4 | 4 | | 4 | 11 |
| 5 | 4 | | 5 | 12 |
| 6 | 7 | +---------------------+
| 7 | 9 |
| 8 | 11 |
| 9 | 11 |
| 10 | 12 |
+---------------------+
然后,我想要一个返回以下结果表的映射:
Result:
+---------------------+
| BucketID | ItemID |
+---------------------+
| 1 | 1 |
| 2 | 2 |
| 3 | NULL |
| 4 | NULL |
| 5 | NULL |
| 6 | 3 |
| 7 | NULL |
| 8 | 4 |
| 9 | NULL |
| 10 | 5 |
+---------------------+
因为没有外键关系或其他东西,我可以将列修复到它们相应的存储桶(但只有关系 Bucket.Size >= Item.Size),我在使用有效 SQL 描述结果时遇到了很多麻烦询问。每当我使用连接或子选择时,我都会得到桶中的项目,这些项目太大了(比如在大小为 12 的桶中有一个大小为 2 的项目,而大小为 2 的桶仍然可用)或者我得到相同的项目多个桶。
我现在花了一些时间自己寻找解决方案,我几乎可以说,最好不要在 SQL 中声明问题,而在应用程序中声明问题,这只是获取表。
你认为这个任务在 SQL 中可行吗?如果是这样,如果你能帮我解决一个有效的问题,我将不胜感激。
编辑:查询应该至少兼容 Oracle、Postgres 和 SQLite 数据库
编辑 II:带有给定测试集的 SQL Fiddle 在示例查询上方,返回错误结果,但接近于结果可能的样子 http://sqlfiddle.com/#!15/a6c30/1
最佳答案
试试这个...我能够使用 recursive CTE
实现这一点,全部在 1 个 SQL 语句中
我的唯一假设是Bucket 和 Item 数据集已排序。
DECLARE @BUCKET TABLE
(
BUCKETID INT
, SIZE INT
)
DECLARE @ITEM TABLE
(
ITEMID INT
, SIZE INT
)
;
INSERT INTO @BUCKET
SELECT 1,2 UNION ALL
SELECT 2,2 UNION ALL
SELECT 3,2 UNION ALL
SELECT 4,4 UNION ALL
SELECT 5,4 UNION ALL
SELECT 6,7 UNION ALL
SELECT 7,9 UNION ALL
SELECT 8, 11 UNION ALL
SELECT 9, 11 UNION ALL
SELECT 10,12
INSERT INTO @ITEM
SELECT 1,2 UNION ALL
SELECT 2,2 UNION ALL
SELECT 3,5 UNION ALL
SELECT 4,11 UNION ALL
SELECT 5,12;
WITH TOTAL_BUCKETS
AS (
SELECT MAX(BUCKETID) CNT
FROM @BUCKET
) -- TO GET THE TOTAL BUCKETS COUNT TO HALT THE RECURSION
, CTE
AS (
--INVOCATION PART
SELECT BUCKETID
, (
SELECT MIN(ITEMID)
FROM @ITEM I2
WHERE I2.SIZE <= (
SELECT SIZE
FROM @BUCKET
WHERE BUCKETID = (1)
)
) ITEMID --PICKS THE FIRST ITEM ID MATCH FOR THE BUCKET SIZE
, BUCKETID + 1 NEXT_BUCKETID --INCREMENT FOR NEXT BUCKET ID
, (
SELECT ISNULL(MIN(ITEMID), 0)
FROM @ITEM I2
WHERE I2.SIZE <= (
SELECT SIZE
FROM @BUCKET
WHERE BUCKETID = (1)
)
) --PICK FIRST ITEM ID MATCH
+ (
CASE
WHEN (
SELECT ISNULL(MIN(ITEMID), 0)
FROM @ITEM I3
WHERE I3.SIZE <= (
SELECT SIZE
FROM @BUCKET
WHERE BUCKETID = (1)
)
) IS NOT NULL
THEN 1
ELSE 0
END
) NEXT_ITEMID --IF THE ITEM IS PLACED IN THE BUCKET THEN INCREMENTS THE FIRST ITEM ID
, (
SELECT SIZE
FROM @BUCKET
WHERE BUCKETID = (1 + 1)
) NEXT_BUCKET_SIZE --STATES THE NEXT BUCKET SIZE
FROM @BUCKET B
WHERE BUCKETID = 1
UNION ALL
--RECURSIVE PART
SELECT NEXT_BUCKETID BUCKETID
, (
SELECT ITEMID
FROM @ITEM I2
WHERE I2.SIZE <= NEXT_BUCKET_SIZE
AND I2.ITEMID = NEXT_ITEMID
) ITEMID -- PICKS THE ITEM ID IF IT IS PLACED IN THE BUCKET
, NEXT_BUCKETID + 1 NEXT_BUCKETID --INCREMENT FOR NEXT BUCKET ID
, NEXT_ITEMID + (
CASE
WHEN (
SELECT I3.ITEMID
FROM @ITEM I3
WHERE I3.SIZE <= NEXT_BUCKET_SIZE
AND I3.ITEMID = NEXT_ITEMID
) IS NOT NULL
THEN 1
ELSE 0
END
) NEXT_ITEMID --IF THE ITEM IS PLACED IN THE BUCKET THEN INCREMENTS THE CURRENT ITEM ID
, (
SELECT SIZE
FROM @BUCKET
WHERE BUCKETID = (NEXT_BUCKETID + 1)
) NEXT_BUCKET_SIZE --STATES THE NEXT BUCKET SIZE
FROM CTE
WHERE NEXT_BUCKETID <= (
SELECT CNT
FROM TOTAL_BUCKETS
) --HALTS THE RECURSION
)
SELECT
BUCKETID
, ITEMID
FROM CTE
关于sql - SQL弱关联表字段映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22539962/
请看一下我的代码。 int main () { Program* allcommand = new Program; allcommand->addCommand("add", new
因此,当我遇到调试断言时,我正在编写代码。现在我很想知道为什么这段代码不起作用: for(Model::MeshMap::iterator it = obj1->GetMeshes().begin()
这是我上一个问题的延续 Group, Sum byType then get diff using Java streams . 按照建议,我应该作为单独的线程发布,而不是更新原始线程。 因此,通过我
我正在实现一些非常适合 map 的代码。但是,我要迭代的列表中有大量对象,所以我的问题是哪种方法是解决此问题的最佳方法: var stuff = $.map(listOfMyObjects, some
我正在尝试创建一个包含不同类的成员函数指针的映射。成员函数都具有相同的签名。为了做到这一点,我所有的类都继承了一个 Object 类,它只有默认构造函数、虚拟析构函数和一个虚拟 ToString()
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: how do you make a heterogeneous boost::map? 有可能在 C++ 中
我有一个 Mysql 查询,请检查以下内容: SELECT `tbl_classSubjects`.`classID` , `tbl_classSubjects`.`sectionID` , `tbl
抱歉,这可能是一个基本问题。 JNA直接映射和接口(interface)映射有什么区别? 我的解释是否正确: 直接映射 : 直接使用库对象(如 Java 中的静态 main) 接口(interface
在 Twitter's Scala school collections section ,它们显示了一个带有偏函数作为值的 Map: // timesTwo() was defined earlie
很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。如需帮助澄清这个问题以便重新打开它,visit the help center .
据我了解,从 scala stdlib 声明一个映射并没有将其专门用于原始类型。我要的不是付出装箱/拆箱的代价,而是同时拥有scala map 的接口(interface)。一个明显的选择是使用 tr
如何为这样的 JSON 响应创建对象映射,它只是一个整数数组: [ 565195, 565309, 565261, 565515, 565292, 565281, 566346, 5
是否可以为 DTO 对象创建映射然后查询它们 而不是域?如果不解释为什么? 如果我需要几个 dtos 怎么办? DTos 是只读的 ID 由 NH 自动生成 将来这些 dtos 将设置映射到链接的 d
我有一个返回的函数(常规代码) [words: "one two", row: 23, col: 45] 在 Scala 中,我将上面更改为 Scala Map,但随后我被迫将其声明为 Map[Str
我有一组与 Vanilla 磅蛋糕烘焙相关的数据(200 行),具有 27 个特征,如下所示。标签caketaste是衡量烤蛋糕的好坏程度,由 bad(0) 定义, neutral(1) , good
我有试图映射到新代码的遗留代码。 OLD_PERSON pid sid name age NEW_PERSON pid sid fid age RESOLVE_PERSON pid fid statu
我有一个表,其中一个字段可以指向其他 3 个表之一中的外键,具体取决于鉴别器值是什么(Project、TimeKeep 或 CostCenter。通常这是用子类实现的,我想知道我有什么 注意子类名称与
我有一个类型 [ST s (Int, [Int])] 的绑定(bind)我正在尝试申请runST使用映射到每个元素,如下所示: name :: [ST s (Int, [Int])] --Of Cou
在我正在进行的项目中,我有以下实体:分析师、客户 和承包商。每个都继承自基类 User。 public abstract class User { public virtual int Id
我想知道是否可以在 Vim 中创建一个映射(对于普通模式),允许用户在映射执行之前输入。 我想为我最常用的 grep 命令创建一个快捷方式的映射。我希望命令允许输入我正在搜索的内容,然后在输入时执行。
我是一名优秀的程序员,十分优秀!