Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按值的最小值对值进行分组,然后按值本身对其他字段进行排序_Sql_Oracle - Fatal编程技术网

Sql 按值的最小值对值进行分组,然后按值本身对其他字段进行排序

Sql 按值的最小值对值进行分组,然后按值本身对其他字段进行排序,sql,oracle,Sql,Oracle,我想按聚合值、其他字段、未聚合值对数据进行排序 我有以下模式: CREATE TABLE priority_t ( id NUMERIC(10), priority NUMERIC(10), CONSTRAINT priority_t_pk PRIMARY KEY (id) ); CREATE TABLE value_t ( id NUMERIC(10), value NUMERIC(10), CONSTRAINT

我想按聚合值、其他字段、未聚合值对数据进行排序

我有以下模式:

CREATE TABLE priority_t (
  id          NUMERIC(10),
  priority    NUMERIC(10),
  CONSTRAINT priority_t_pk PRIMARY KEY (id)
);

CREATE TABLE value_t (
  id          NUMERIC(10),
  value       NUMERIC(10),
  CONSTRAINT value_t_pk PRIMARY KEY (id)
);

CREATE TABLE file_t (
  id          NUMERIC(10),
  CONSTRAINT file_t_pk PRIMARY KEY (id)
);

CREATE TABLE main_t (
  id          NUMERIC(10),
  priority_id NUMERIC(10),
  value_id    NUMERIC(10),
  file_id     NUMERIC(10),
  CONSTRAINT main_t_pk PRIMARY KEY (id),
  CONSTRAINT priority_t_fk FOREIGN KEY (priority_id) REFERENCES priority_t(id),
  CONSTRAINT value_t_fk FOREIGN KEY (value_id) REFERENCES value_t(id),
  CONSTRAINT file_t_fk FOREIGN KEY (file_id) REFERENCES file_t(id)
);
然后我插入以下数据:

INSERT INTO priority_t (id, priority) VALUES (1, 10);
INSERT INTO priority_t (id, priority) VALUES (2, 20);

INSERT INTO value_t (id, value)       VALUES (1, 987);
INSERT INTO value_t (id, value)       VALUES (2, 876);
INSERT INTO value_t (id, value)       VALUES (3, 765);
INSERT INTO value_t (id, value)       VALUES (4, 654);

INSERT INTO file_t (id)               VALUES (111);
INSERT INTO file_t (id)               VALUES (222);
INSERT INTO file_t (id)               VALUES (333);
INSERT INTO file_t (id)               VALUES (444);

INSERT INTO main_t  (id, priority_id, value_id, file_id) VALUES (1, 1, 1, 111);
INSERT INTO main_t  (id, priority_id, value_id, file_id) VALUES (2, 2, 1, 111);
INSERT INTO main_t  (id, priority_id, value_id, file_id) VALUES (3, 2, 2, 222);
INSERT INTO main_t  (id, priority_id, value_id, file_id) VALUES (4, 1, 2, 333);
INSERT INTO main_t  (id, priority_id, value_id, file_id) VALUES (5, 2, 3, 111);
INSERT INTO main_t  (id, priority_id, value_id, file_id) VALUES (6, 1, 4, 444);
INSERT INTO main_t  (id, priority_id, value_id, file_id) VALUES (7, 2, 4, 444);

COMMIT;
我想得到以下结果:

 min_priority | priority | value | value_id | file_id
   (hidden)   |          |       | (hidden) |        
--------------+----------+-------+----------+---------
           10 |       10 |   654 |        4 |     444 
           10 |       20 |   654 |        4 |     444
           10 |       10 |   876 |        2 |     333
           10 |       10 |   987 |        1 |     111
           10 |       20 |   987 |        1 |     111
           20 |       20 |   765 |        3 |     111
           20 |       20 |   876 |        2 |     222
我知道如何分类:

ORDER BY min_value ASC, value ASC, value_id ASC, priority ASC
但我的问题是,我不知道如何对值本身进行分组:我的行中不断出现重复的值和/或不正确的值

我最近的尝试如下:

WITH listing AS (
  SELECT m.id             AS main_id,
         p.id             AS priority_id,
         p.priority       AS priority,
         v.id             AS value_id,
         v.value          AS value,
         f.id             AS file_id
    FROM main_t m
           INNER JOIN priority_t p ON m.priority_id = p.id
           INNER JOIN value_t v    ON m.value_id = v.id
           INNER JOIN file_t f     ON m.file_id = f.id
)
SELECT min_p.min_priority AS min_priority,
       listing.priority   AS priority,
       listing.value      AS value,
       listing.file_id    AS file_id
  FROM listing,
       (
         SELECT min(min_p_value.min_priority) AS min_priority,
                min_p_value.value_id          AS min_value_id,
                listing.file_id               AS file_id
           FROM listing,
                (
                  SELECT min(listing.priority) AS min_priority,
                         listing.value         AS value,
                         listing.value_id      AS value_id
                    FROM listing
                   GROUP BY listing.value, listing.value_id
                ) min_p_value
          WHERE listing.value = min_p_value.value
            AND listing.value_id = min_p_value.value_id
            AND min_p_value.min_priority = min_priority
          GROUP BY min_p_value.value_id, listing.file_id
       ) min_p
 WHERE min_p.min_value_id = listing.value_id
   AND min_p.file_id = listing.file_id
 ORDER BY min_p.min_priority ASC,
          listing.value ASC,
          listing.value_id ASC,
          listing.priority;
这将返回以下不正确的结果:

 MIN_PRIORITY   PRIORITY      VALUE    FILE_ID
------------- ---------- ---------- ----------
           10         10        654        444
           10         20        654        444
           10         10        876        333
           10         20        876        222 <-- incorrect, should have a min_priority of 20, and therefore be the last
           10         10        987        111
           10         20        987        111
           20         20        765        111
MIN\u优先级值文件\u ID
------------- ---------- ---------- ----------
10         10        654        444
10         20        654        444
10         10        876        333

10 20 876 222我用MySQL(不是Oracle)编写了这段代码,不确定CTE语法,所以我用名为minu priority的临时表替换了WITH子句,但是您当然可以用CTE替换临时表。当我在MySQl上运行这个时,我得到了与您想要的相同的结果

也不确定是否需要左连接或内连接,这两种连接在本例中都有效

-- find min priority for each value
create temporary table if not exists min_priority as (
select m.value_id, min(p.priority) as min_pri
from main_t m
inner join priority_t p on m.priority_id = p.id
group by m.value_id
);

-- just join all the tables, including min_priority, and order the result
select mp.min_pri, p.priority, v.value, v.id, f.id
from main_t m
left join priority_t p on m.priority_id = p.id
left join value_t v on m.value_id = v.id
left join file_t f on m.file_id = f.id
left join min_priority mp on mp.value_id = v.id
order by mp.min_pri asc, v.value asc, v.id asc, p.priority asc;
作为旁注,我不会像你在问题中的例子那样使用多个级别的内部查询,因为它们会影响性能。

这应该可以:

select (select min(priority)
          from main_t mm
          join priority_t tt
            on tt.id = mm.priority_id
         where mm.value_id = m.value_id) as min_priority,
       p.priority as priority,
       v.value as value,
       m.value_id,
       m.file_id
  from main_t m
  join priority_t p
    on p.id = m.priority_id
  join value_t v
    on v.id = m.value_id
 order by 1, 3, 4, 2;
它通过值_id确定最小优先级。
您可以按列编号对结果进行排序,如图所示。

当需要使用聚合值和非聚合值时。我想,应该是这样的:

select *
  from (select min(p.priority) over (partition by v.id, v.value, f.id) min_priority, 
               p.priority, v.value, v.id value_id, f.id file_id 
          from main_t m
          join priority_t p on m.priority_id = p.id
          join value_t v    on m.value_id = v.id
          join file_t f     on m.file_id = f.id)
  order by min_priority, value, value_id, priority
结果:

MIN_PRIORITY    PRIORITY       VALUE    VALUE_ID     FILE_ID
------------ ----------- ----------- ----------- -----------
          10          10         654           4         444
          10          20         654           4         444
          10          10         876           2         333
          10          10         987           1         111
          10          20         987           1         111
          20          20         765           3         111
          20          20         876           2         222

看起来你想要的结果与给定的测试数据不符。value_id=3在结果中出现两次,但在您的测试数据中只出现一次?@FrankOckenfuss谢谢,您是对的:我期待的是
value_id=2,value=876
而不是
value_id=3,value=765
。我修正了这个问题。你想按值\ id对最小(优先级)进行分组吗?@Frankockenfoss是的,分组必须先按值/值\ id进行,然后按最小优先级(然后按文件\ id或其他任何字段)进行。这似乎是正确的。我会接受你的回答。但是,我忘记了问题中的一个具体案例,意思是我不应该看到重复项(基于
min\u优先级、值、文件id
——文件id存在的全部原因)。适应这些琐碎的事情吗?如果没有,我将创建一个单独的问题。我想您希望根据优先级、值、文件id删除重复项?否,
min\u优先级
。不管怎样,我们找到了一种使用流水线函数的方法,这是Oracle的一种特性。无论如何谢谢你!:-)