2017-09-04 7 views
1

FirebirdSQL 3.0.2を使用しています。私はそれに固定された行とレポートを引き出すしようとしています。意味、私は毎回特定の数の行を持っていたいと思います。結果セットに特定の行が存在しない場合は、値がゼロの欠落行を表示したいと思います。FirebirdSQL共用レコード

私はダミーテーブルRAPOR_EKをすべての行の組み合わせを行として含めています。私はメインのレポートのSQLにUNIONを使ってテーブルを選択します。

私の問題は、重複するレコードについてです。私のメイン・レポートのSQLでレコードが選択されている場合、ダミー・テーブルから選択されたレコードが1つあります。

テーブル構造、ダミーテーブルレコード、レポートSQL、およびレポートSQL出力が以下に含まれています。レポートのSQL出力では、行番号1,2,5,6,7,8などのレコードが重複して表示されます。

何か助けていただきありがとうございます。

生データテーブルDDL

CREATE TABLE TABLO_MEDAS (
ID BIGINT NOT NULL, 
T_GERIBILDIRIMNO INTEGER, 
T_ILANTARIHI TIMESTAMP, 
T_KODNO INTEGER, 
T_KADEME SMALLINT, 
T_IL VARCHAR(15), 
T_ILCE VARCHAR(20), 
T_SEBEKEUNSURU VARCHAR(220), 
T_KESINTINEDENIILISKIACIKLAMA VARCHAR(250), 
TKS_KAYNAGAGORE VARCHAR(20), 
TKS_SUREYEGORE VARCHAR(10), 
TKS_SEBEBEGORE VARCHAR(20), 
T_BILDIRIMEGORE VARCHAR(15), 
T_BASLAMATARIHI TIMESTAMP, 
T_SONAERMETARIHI TIMESTAMP, 
T_KESINTISURESI DOUBLE PRECISION, 
TEKS_IMARALANICIOG DOUBLE PRECISION, 
TEKS_IMARALANICIAG DOUBLE PRECISION, 
TEKS_IMARALANDISIOG DOUBLE PRECISION, 
TEKS_IMARALANDISIAG DOUBLE PRECISION, 
TES_IMARALANICIOG DOUBLE PRECISION, 
TES_IMARALANICIAG DOUBLE PRECISION, 
TES_IMARALANDISIOG DOUBLE PRECISION, 
TES_IMARALANDISIAG DOUBLE PRECISION, 
T_ISLETME VARCHAR(50), 
T_SURE VARCHAR(25), 
CONSTRAINT PK_TABLO_MEDAS PRIMARY KEY (ID) 
); 

ダミーテーブルDDL

CREATE TABLE RAPOR_EK (
    KAYNAK VARCHAR(30), 
    SEBEP VARCHAR(30) 
) ; 

レポートSQL

select 
    '2015-01-01' AS "TARIH", 
    10 AS "RAPOR_TURU", 
    M.TKS_KAYNAGAGORE AS "KAYNAK", 
    M.TKS_SEBEBEGORE AS "SEBEP", 
    (sum(M.TEKS_IMARALANICIOG)/(select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IAIK_OG", 
    (sum(M.TEKS_IMARALANICIAG)/(select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IAIK_AG", 
    ((sum(M.TEKS_IMARALANICIOG) + sum(M.TEKS_IMARALANICIAG))/((select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))) AS "IAIK_TOPLAM", 
    (sum(M.TEKS_IMARALANDISIOG)/(select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IADK_OG", 
    (sum(M.TEKS_IMARALANDISIAG)/(select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IADK_AG", 
    ((sum(M.TEKS_IMARALANDISIOG) + sum(M.TEKS_IMARALANDISIAG))/((select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))) AS "IADK_TOPLAM", 
    ((sum(M.TEKS_IMARALANICIOG) + sum(M.TEKS_IMARALANICIAG) + (sum(M.TEKS_IMARALANDISIOG) + sum(M.TEKS_IMARALANDISIAG)))/((select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))) AS "GNLTOPLAM" 
from TABLO_MEDAS M 
where 
    M.T_ILCE = 'CİHANBEYLİ' 
    and T_BILDIRIMEGORE = 'Bildirimsiz' 
    and (T_BASLAMATARIHI >= '2015-01-01' and T_BASLAMATARIHI <= '2015-01-31 23:59:59') 
group by 
    M.TKS_KAYNAGAGORE, 
    M.TKS_SEBEBEGORE 

UNION 

SELECT 
    '2015-01-01' AS "TARIH", 
    10 AS "RAPOR_TURU", 
    KAYNAK, 
    SEBEP, 
    0, 
    0, 
    0, 
    0, 
    0, 
    0, 
    0 
FROM 
    RAPOR_EK 

のダミーテーブルのレコード

KAYNAK SEBEP 
Dağıtım-AG Dışsal 
Dağıtım-AG Şebeke işletmecisi 
Dağıtım-AG Mücbir Sebep 
Dağıtım-AG Güvenlik 
Dağıtım-OG Dışsal 
Dağıtım-OG Şebeke işletmecisi 
Dağıtım-OG Mücbir Sebep 
Dağıtım-OG Güvenlik 
İletim Sistemi Şebeke işletmecisi 
İletim Sistemi Mücbir Sebep 
İletim Sistemi Dışsal 
İletim Sistemi Güvenlik 

レポートSQL出力

TARIH RAPOR_TURU KAYNAK SEBEP IAIK_OG IAIK_AG IAIK_TOPLAM IADK_OG IADK_AG IADK_TOPLAM GNLTOPLAM 
2015-01-01 10 Dağıtım-AG Dışsal 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-AG Dışsal 0 0.00046546808634433004 0.000462962962962963 0 0.003875217981011432 0.0028260562385191467 0.0011495668596296753 
2015-01-01 10 Dağıtım-AG Güvenlik 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-AG Mücbir Sebep 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-AG Şebeke işletmecisi 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-AG Şebeke işletmecisi 0 0.0402048059579915 0.03998842592592593 0 0.09726797132338694 0.07093401158683058 0.04897975941207866 
2015-01-01 10 Dağıtım-OG Dışsal 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-OG Dışsal 0 0.052365159713737126 0.052083333333333336 0.042275574112734866 0 0.011445527766002543 0.04027589604631112 
2015-01-01 10 Dağıtım-OG Güvenlik 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-OG Güvenlik 0.16129032258064516 0.0005818351079304125 0.0014467592592592592 0 0 0 0.00102639898181221 
2015-01-01 10 Dağıtım-OG Mücbir Sebep 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-OG Şebeke işletmecisi 0 0 0 0 0 0 0 
2015-01-01 10 Dağıtım-OG Şebeke işletmecisi 0.6881720430107527 0.8316751032757317 0.8309027777777778 2.8491649269311066 1.3673706645998838 1.768545994065282 1.1033378494888533 
2015-01-01 10 İletim Sistemi Dışsal 0 0 0 0 0 0 0 
2015-01-01 10 İletim Sistemi Güvenlik 0 0 0 0 0 0 0 
2015-01-01 10 İletim Sistemi Mücbir Sebep 0 0 0 0 0 0 0 
2015-01-01 10 İletim Sistemi Şebeke işletmecisi 0 0 0 0 0 0 0 

編集: SQLの下に使用してはTABLO_MEDASだけに存在行を返します。次のように

SELECT 
    '2015-01-01' AS "TARIH", 
    10 AS "RAPOR_TURU", 
    RAPOR_EK.KAYNAK, 
    RAPOR_EK.SEBEP, 
    (sum(M.TEKS_IMARALANICIOG)/(select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IAIK_OG", 
    (sum(M.TEKS_IMARALANICIAG)/(select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IAIK_AG", 
    ((sum(M.TEKS_IMARALANICIOG) + sum(M.TEKS_IMARALANICIAG))/((select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))) AS "IAIK_TOPLAM", 
    (sum(M.TEKS_IMARALANDISIOG)/(select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IADK_OG", 
    (sum(M.TEKS_IMARALANDISIAG)/(select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')) as "IADK_AG", 
    ((sum(M.TEKS_IMARALANDISIOG) + sum(M.TEKS_IMARALANDISIAG))/((select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))) AS "IADK_TOPLAM", 
    ((sum(M.TEKS_IMARALANICIOG) + sum(M.TEKS_IMARALANICIAG) + (sum(M.TEKS_IMARALANDISIOG) + sum(M.TEKS_IMARALANDISIAG)))/((select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))) AS "GNLTOPLAM" 
FROM 
    RAPOR_EK 
LEFT JOIN TABLO_MEDAS AS M ON M.TKS_KAYNAGAGORE = RAPOR_EK.KAYNAK AND M.TKS_SEBEBEGORE = RAPOR_EK.SEBEP 
where 
    M.T_ILCE = 'CİHANBEYLİ' 
    and T_BILDIRIMEGORE = 'Bildirimsiz' 
    and (T_BASLAMATARIHI >= '2015-01-01' and T_BASLAMATARIHI <= '2015-01-31 23:59:59') 
group by 
    KAYNAK, 
    SEBEP 

ワーキングSQLは次のとおりです。

SELECT 
    RAPOR_EK.KAYNAK, 
    RAPOR_EK.SEBEP, 
    COALESCE(DT.IAIK_OG, 0) AS "IAIK_OG", 
    COALESCE(DT.IAIK_AG, 0) AS "IAIK_AG", 
    COALESCE(DT.IAIK_TOPLAM, 0) AS "IAIK_TOPLAM", 
    COALESCE(DT.IADK_OG, 0) AS "IADK_OG", 
    COALESCE(DT.IADK_AG, 0) AS "IADK_AG", 
    COALESCE(DT.IADK_TOPLAM, 0) AS "IADK_TOPLAM", 
    COALESCE(DT.GNLTOPLAM, 0) AS "GNLTOPLAM" 
FROM RAPOR_EK 
LEFT JOIN (
    SELECT 
    M.TKS_KAYNAGAGORE AS "KAYNAK", 
    M.TKS_SEBEBEGORE AS "SEBEP", 
    (sum(M.TES_IMARALANICIOG)/(select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')*60) as "IAIK_OG", 
    (sum(M.TES_IMARALANICIAG)/(select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')*60) as "IAIK_AG", 
    ((sum(M.TES_IMARALANICIOG) + sum(M.TES_IMARALANICIAG))/((select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))*60) AS "IAIK_TOPLAM", 
    (sum(M.TES_IMARALANDISIOG)/(select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')*60) as "IADK_OG", 
    (sum(M.TES_IMARALANDISIAG)/(select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ')*60) as "IADK_AG", 
    ((sum(M.TES_IMARALANDISIOG) + sum(M.TES_IMARALANDISIAG))/((select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))*60) AS "IADK_TOPLAM", 
    ((sum(M.TES_IMARALANICIOG) + sum(M.TES_IMARALANICIAG) + (sum(M.TES_IMARALANDISIOG) + sum(M.TES_IMARALANDISIAG)))/((select sum(I.ILC_IMARALANICI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANICI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_OG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ') + (select sum(I.ILC_IMARALANDISI_AG) from ILCELER_TABLOSU I where I.ILCEADI = 'CİHANBEYLİ'))*60) AS "GNLTOPLAM" 
    FROM TABLO_MEDAS M 
    WHERE 
    M.T_ILCE = 'CİHANBEYLİ' 
    AND M.T_BILDIRIMEGORE = 'Bildirimsiz' 
    AND M.TKS_SUREYEGORE = 'Uzun' 
    AND (M.T_BASLAMATARIHI >= '2015-01-01' AND T_BASLAMATARIHI <= '2015-01-31 23:59:59') 
    GROUP BY 
    M.TKS_KAYNAGAGORE, 
    M.TKS_SEBEBEGORE 
) DT USING (KAYNAK, SEBEP) 
ORDER BY KAYNAK, SEBEP 
+0

と参加using (report_id_1, report_id_2)を交換する必要があるかもしれませんアウターはRAPOR_EK'とLEFT OUTER ''のようなTABLO_MEDAS' –

+0

試み何か '間の結合のみTABLO_MEDAS''中に存在する行を表示し、M.TKS_KAYNAGAGORE = R.KAYNAK AND M.TKS_SEBEBEGORE = R.SEBEP' ON R AS RAPOR_EKをJOIN 'RAPOR_EK'のレコードは表示されません。 RAPOR_EKが上TABLO_MEDASに参加左から –

+0

あなたは '欲しい...' 'RAPOR_EK'は**あなたが望むすべての**行が含まれている場合は、そうでなければ、私はSQLが得意ではないです'完全外部join' –

答えて

1

は、データの複雑さを考えると、私は解決策を実証するための単純化されたスキーマを作成しました:

report_sourceがあり
create table report_source (
    REPORT_ID_1 VARCHAR(25) NOT NULL, 
    REPORT_ID_2 VARCHAR(25) NOT NULL, 
    CONSTRAINT PK_REPORT_SOURCE PRIMARY KEY (REPORT_ID_1, REPORT_ID_2) 
); 

create table report_data (
    REPORT_ID_1 VARCHAR(25) NOT NULL, 
    REPORT_ID_2 VARCHAR(25) NOT NULL, 
    VALUE_1 INT, 
    VALUE_2 INT 
); 

insert into report_source (report_id_1, report_id_2) values ('a', 'a'); 
insert into report_source (report_id_1, report_id_2) values ('a', 'b'); 
insert into report_source (report_id_1, report_id_2) values ('b', 'a'); 
insert into report_source (report_id_1, report_id_2) values ('b', 'b'); 

insert into report_data (report_id_1, report_id_2, value_1, value_2) values ('a', 'a', 1, 2); 
insert into report_data (report_id_1, report_id_2, value_1, value_2) values ('b', 'b', 3, 4); 

rapor_ekと同じ役割、report_datatablo_medasの役割です。

select src.report_id_1, src.report_id_2, 
    coalesce(dt.value_1, 0) as value_1, 
    coalesce(dt.value_2, 0) as value_2 
from report_source src 
left join report_data dt using (report_id_1, report_id_2) 

得られます:

a a 1 2 
a b 0 0 
b a 0 0 
b b 3 4 

は今、必要なデータを取得するために、我々は、デフォルト値でnull値を置き換え、report_sourceからすべての行を選択して、report_dataに参加し、左しかし、あなたのコードはそれほど単純ではありません。なぜなら、left-joinをinner joinに変換するwhere節にも条件があるからです。デフォルト値を使用してレポートデータを取得するには、そのクエリは、他の言葉で、report_dataの場所を取る必要があります。

select src.report_id_1, src.report_id_2, 
    coalesce(dt.value_1, 0) as value_1, 
    coalesce(dt.value_2, 0) as value_2 
from report_source src 
left join (
    select * 
    from report_data 
    where <conditions> 
    <group by, etc> 
) dt using (report_id_1, report_id_2) 

また、私はあなたがしたいと思いますon dt.report_id_1 = src.report_id_1 and dt.report_id_1 = src.report_id_2

+0

'using(report_id_1、report_id_2)'を使用する必要がありますか、それとも使用することができますか?私のテストでは、2つのバージョンが同じように動作していることがわかります。 –

+0

@ErtanKüçükogluいいえ、私の最後の段落を参照してください。 'using'は短くても、両方のテーブルの列が同じ名前を持つ場合にのみ使用できます。 「下の[Firebirdの言語リファレンス](https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-select.html#fblangref25-dml-select-joins-qualified)を参照してください。名前付き結合 " –

関連する問題