سؤال

لدي الاستعلام التالي:

SELECT sum((select count(*) as itemCount) * "SalesOrderItems"."price") as amount, 'rma' as     
    "creditType", "Clients"."company" as "client", "Clients".id as "ClientId", "Rmas".* 
FROM "Rmas" JOIN "EsnsRmas" on("EsnsRmas"."RmaId" = "Rmas"."id") 
    JOIN "Esns" on ("Esns".id = "EsnsRmas"."EsnId") 
    JOIN "EsnsSalesOrderItems" on("EsnsSalesOrderItems"."EsnId" = "Esns"."id" ) 
    JOIN "SalesOrderItems" on("SalesOrderItems"."id" = "EsnsSalesOrderItems"."SalesOrderItemId") 
    JOIN "Clients" on("Clients"."id" = "Rmas"."ClientId" )
WHERE "Rmas"."credited"=false AND "Rmas"."verifyStatus" IS NOT null 
GROUP BY "Clients".id, "Rmas".id;

المشكلة هي أن الجدول "EsnsSalesOrderItems" يمكن أن يكون لها نفس الشيء EsnId في إدخالات مختلفة.أريد تقييد الاستعلام لسحب الإدخال الأخير فقط "EsnsSalesOrderItems" هذا له نفس الشيء "EsnId".

عن طريق إدخال" آخر " أعني ما يلي:

الذي يظهر آخر في الجدول "EsnsSalesOrderItems".لذلك على سبيل المثال إذا "EsnsSalesOrderItems" لديه اثنين من الإدخالات مع "EsnId" = 6 و "createdAt" = '2012-06-19' و '2012-07-19' على التوالي يجب أن تعطيني فقط الدخول من '2012-07-19'.

هل كانت مفيدة؟

المحلول

SELECT (count(*) * sum(s."price")) AS amount
     , 'rma'       AS "creditType"
     , c."company" AS "client"
     , c.id        AS "ClientId"
     , r.* 
FROM   "Rmas"            r
JOIN   "EsnsRmas"        er ON er."RmaId" = r."id"
JOIN   "Esns"            e  ON e.id = er."EsnId"
JOIN  (
   SELECT DISTINCT ON ("EsnId") *
   FROM   "EsnsSalesOrderItems"
   ORDER  BY "EsnId", "createdAt" DESC
   )                     es ON es."EsnId" = e."id"
JOIN   "SalesOrderItems" s  ON s."id" = es."SalesOrderItemId"
JOIN   "Clients"         c  ON c."id" = r."ClientId"
WHERE  r."credited" = FALSE
AND    r."verifyStatus" IS NOT NULL 
GROUP  BY c.id, r.id;

يحتوي استفسارك في السؤال على تجميع غير قانوني على إجمالي آخر:

sum((select count(*) as itemCount) * "SalesOrderItems"."price") as amount

مبسطة وتحويلها إلى بناء الجملة القانوني:

(count(*) * sum(s."price")) AS amount

ولكن هل تريد حقا أن تتضاعف مع عدد لكل مجموعة?

أنا استرداد صف واحد لكل مجموعة في "EsnsSalesOrderItems" مع DISTINCT ON.شرح مفصل:

وأضفت أيضا الأسماء المستعارة الجدول والتنسيق لجعل الاستعلام أسهل لتحليل للعيون البشرية.إذا كنت تستطيع تجنب حالة الجمل هل يمكن التخلص من جميع علامات الاقتباس المزدوجة تغيم المنظر.

نصائح أخرى

شيء مثل:

join (
  select "EsnId", 
         row_number() over (partition by "EsnId" order by "createdAt" desc) as rn
  from "EsnsSalesOrderItems"
) t ON t."EsnId" = "Esns"."id" and rn = 1

سيؤدي هذا إلى تحديد الأحدث "EsnId" من "EsnsSalesOrderItems" على أساس العمود creation_date.نظرًا لأنك لم تنشر بنية جداولك، فقد اضطررت إلى "ابتكار" اسم عمود.يمكنك استخدام أي عمود يسمح لك بتحديد ترتيب على الصفوف التي تناسبك.

لكن تذكر أن مفهوم "الصف الأخير" يكون صالحًا فقط إذا قمت بتحديد طلب أو صفوف.لا يتم ترتيب الجدول على هذا النحو، ولا يكون نتيجة استعلام إلا إذا قمت بتحديد order by

استحضار الأرواح لأن الإجابات قديمة.
الاستفادة من LATERAL الكلمة الرئيسية المقدمة في الصفحة 9.3

اليسار | الحق | صلة داخلية جانبي

سأشرح بمثال:
على افتراض أن لديك جدول "جهات الاتصال".
الآن تحتوي جهات الاتصال على وحدات تنظيمية.
يمكن أن يكون لديهم وحدة تنظيمية واحدة في وقت ما، لكن N OUs في N نقطة زمنية.

الآن، إذا كان عليك الاستعلام عن جهات الاتصال والوحدة التنظيمية في فترة زمنية (ليس تاريخ تقرير، ولكن نطاق تاريخ)، يمكنك زيادة عدد السجلات بمقدار N-fold إذا قمت للتو بربط يسار.
لذا، لعرض الوحدة التنظيمية، تحتاج فقط إلى الانضمام إلى الوحدة التنظيمية الأولى لكل جهة اتصال (حيث يكون ما يجب أن يكون أولاً معيارًا عشوائيًا - عند أخذ القيمة الأخيرة، على سبيل المثال، تكون هذه مجرد طريقة أخرى لقول القيمة الأولى عند الفرز بترتيب التاريخ التنازلي).

في SQL-server، يمكنك استخدام التطبيق المتقاطع (أو بالأحرى التطبيق الخارجي لأننا نحتاج إلى صلة يسارية)، والتي ستستدعي دالة ذات قيمة جدول في كل صف يجب عليه الانضمام إليه.

SELECT * FROM T_Contacts 

--LEFT JOIN T_MAP_Contacts_Ref_OrganisationalUnit ON MAP_CTCOU_CT_UID = T_Contacts.CT_UID AND MAP_CTCOU_SoftDeleteStatus = 1 
--WHERE T_MAP_Contacts_Ref_OrganisationalUnit.MAP_CTCOU_UID IS NULL -- 989

-- CROSS APPLY -- = INNER JOIN 
OUTER APPLY    -- = LEFT JOIN 
(
    SELECT TOP 1 
         --MAP_CTCOU_UID    
         MAP_CTCOU_CT_UID   
        ,MAP_CTCOU_COU_UID  
        ,MAP_CTCOU_DateFrom 
        ,MAP_CTCOU_DateTo   
   FROM T_MAP_Contacts_Ref_OrganisationalUnit 
   WHERE MAP_CTCOU_SoftDeleteStatus = 1 
   AND MAP_CTCOU_CT_UID = T_Contacts.CT_UID 

    /*  
    AND 
    ( 
        (@in_DateFrom <= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateTo) 
        AND 
        (@in_DateTo >= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateFrom) 
    ) 
    */
   ORDER BY MAP_CTCOU_DateFrom 
) AS FirstOE 

في PostgreSQL، بدءًا من الإصدار 9.3، يمكنك فعل ذلك أيضًا - فقط استخدم LATERAL الكلمة الرئيسية لتحقيق نفس الشيء:

SELECT * FROM T_Contacts 

--LEFT JOIN T_MAP_Contacts_Ref_OrganisationalUnit ON MAP_CTCOU_CT_UID = T_Contacts.CT_UID AND MAP_CTCOU_SoftDeleteStatus = 1 
--WHERE T_MAP_Contacts_Ref_OrganisationalUnit.MAP_CTCOU_UID IS NULL -- 989


LEFT JOIN LATERAL 
(
    SELECT 
         --MAP_CTCOU_UID    
         MAP_CTCOU_CT_UID   
        ,MAP_CTCOU_COU_UID  
        ,MAP_CTCOU_DateFrom 
        ,MAP_CTCOU_DateTo   
   FROM T_MAP_Contacts_Ref_OrganisationalUnit 
   WHERE MAP_CTCOU_SoftDeleteStatus = 1 
   AND MAP_CTCOU_CT_UID = T_Contacts.CT_UID 

    /*  
    AND 
    ( 
        (__in_DateFrom <= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateTo) 
        AND 
        (__in_DateTo >= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateFrom) 
    ) 
    */
   ORDER BY MAP_CTCOU_DateFrom 
   LIMIT 1 
) AS FirstOE 

حاول استخدام قاعدة استقامة في جملة ON.مثال مجردة: giveacodicetagpre.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top