Oracle PHP只显示一次

时间:2017-04-07 12:18:40

标签: php oracle

有两个表:

second table

first table

$inner_query = 
    "SELECT A.*, ROWNUM AS RN, TO_CHAR(A.last_newsletter_modify, 'DD/MM/YYYY') AS LAST_NEWSLETTER_MODIFY2
     FROM ".$db_schema_name."newsletter_subscription A,
          ".$db_schema_name."newsletter_type B,
          ".$db_schema_name."newsletter_subtyp_profile C
     WHERE A.id_subscription = C.id_subscription AND
           C.id_type = B.id_type
     ORDER BY e_mail";

如果我为id_subscription 734运行此查询,则会显示3次。

如何只显示一次?

2 个答案:

答案 0 :(得分:1)

简短的回答:每newsletter_subtyp_profile行获得一行。订阅734链接到三种新闻通讯类型,因此有三行输出。

你有三个表,而不是两个表,如果你包含完整的描述和样本数据,问题会更清楚,并且摆脱了不相关的PHP方面,并专注于SQL。

通过一些侦探工作,我这样做:

create table newsletter_subscription
( id_subscription         integer primary key
, last_newsletter_modify  date
, e_mail                  varchar2(50) not null );

create table newsletter_type
( id_type                 integer primary key
, description             varchar2(40) not null unique );

create table newsletter_subtyp_profile
( id_subscription         references newsletter_subscription
, id_type                 references newsletter_type
, constraint nsp_pk       primary key (id_type,id_subscription) );

insert into newsletter_subscription values (600, date '2017-01-10', 'someone@somewhere.net');
insert into newsletter_subscription values (734, date '2017-02-05', 'someone@somewhereelse.net');
insert into newsletter_subscription values (800, date '2017-03-01', 'nobody@nowherewhere.net');

insert into newsletter_type values (1, 'Type One');
insert into newsletter_type values (2, 'Type Two');
insert into newsletter_type values (3, 'Type Three');

insert into newsletter_subtyp_profile values (734, 1);
insert into newsletter_subtyp_profile values (734, 2);
insert into newsletter_subtyp_profile values (734, 3);

现在运行您的查询(我缩短了select列表以简化输出,并添加了b.description - 虚拟列,因为我不知道您在newsletter_type上有哪些其他列):

select a.id_subscription, a.e_mail
     , to_char(a.last_newsletter_modify, 'DD/MM/YYYY') as last_newsletter_modify2
     , b.description
from   newsletter_subscription a,
       newsletter_type b,
       newsletter_subtyp_profile c
where  a.id_subscription = c.id_subscription and
       c.id_type = b.id_type
order by a.e_mail, c.id_type;

ID_SUBSCRIPTION E_MAIL                     LAST_NEWSLETTER_MODIFY2 DESCRIPTION
--------------- -------------------------- ----------------------- ---------------------
            734 someone@somewhereelse.net  05/02/2017              Type One
            734 someone@somewhereelse.net  05/02/2017              Type Two
            734 someone@somewhereelse.net  05/02/2017              Type Three

顺便说一句,如果你为sub使用了a而不是newsletter_subscription等助记别名,那么逻辑会更清晰,并且还使用了标准ANSI连接并丢失了大写:

select sub.id_subscription, sub.e_mail
     , to_char(sub.last_newsletter_modify, 'DD/MM/YYYY') as last_newsletter_modify
     , typ.description
from   newsletter_subscription sub
       join newsletter_subtyp_profile pro on pro.id_subscription = sub.id_subscription
       join newsletter_type typ on typ.id_type = pro.id_type
where  sub.id_subscription = 734
order  by sub.e_mail, pro.id_type;

答案 1 :(得分:0)

您可以使用窗口函数row_number为每个id_subscription获取一行max(如果您将函数中的order by子句更改为order by id_type,则为min id_type):

  $inner_query = "SELECT *
                    FROM (
                        SELECT A.*, 
                            ROWNUM AS RN,
                            TO_CHAR(A.last_newsletter_modify, 'DD/MM/YYYY') AS LAST_NEWSLETTER_MODIFY2,
                            row_number() over (
                                partition by C.id_subscription
                                order by C.id_type desc nulls last
                                ) as seqnum
                        FROM ".$db_schema_name."newsletter_subscription A
                        JOIN ".$db_schema_name."newsletter_subtyp_profile C 
                            on A.id_subscription = C.id_subscription
                        JOIN ".$db_schema_name."newsletter_type B
                            on C.id_type = B.id_type 
                        ) t 
                    WHERE seqnum = 1
                    ORDER BY e_mail";

另请注意,我已使用广泛推荐的显式JOIN语法替换旧的基于逗号的连接。