簡體   English   中英

在不使用臨時表的情況下選擇不同的記錄

[英]Selecting distinct records without using a temporary table

我有一個第三方表,其中填充了一些雜亂的數據,我需要從中獲取最新的不同記錄。 每年或每次“Person”更改時,都會為該表提供一個新行。 該表的工作基於最近的 ActiveDate 是正確的人。 我創建了一個模擬表和數據來顯示這一點。

CREATE TABLE `Persons` (
  `PersonId` varchar(200) NOT NULL,
  `Name` varchar(200) NOT NULL DEFAULT '',
  `ActiveDate` varchar(25) NOT NULL,
  `ExpireDate` varchar(25) DEFAULT NULL,
  `Job` varchar(200) NOT NULL DEFAULT '',
  `Position` varchar(200) NOT NULL DEFAULT ''
)

還有一些模擬數據:

Id       |`Name`        |ActiveDate              |ExpireDate             |Job       |`Position`
---------------------------------------------------------------------------------------------------
J1234    |Doe, John     |2010-08-15 00:00:00     |2011-08-15 00:00:00    |Worker    |Janitor
J1234    |Doe, John     |2011-08-15 00:00:00     |0000-00-00 00:00:00    |Worker    |Janitor
777      |Doe, Jane     |2010-06-04 00:00:00     |0000-00-00 00:00:00    |Boss      |Janitor
777      |Doe, Jane     |2011-04-30 00:00:00     |0000-00-00 00:00:00    |Boss      |Janitor
654G     |Smith, Jane   |2011-01-20 00:00:00     |0000-00-00 00:00:00    |Worker    |Janitor

該表還具有由最終用戶實際設置的 ExpireDate 列,並不總是讓我感到沮喪。 目前我正在使用一個虛擬表將不同的記錄拉出來並存儲一天。 我會使用臨時表,但我不確定如何在 MySQL 中使用,而且我不喜歡它們。 我這樣做的方式只是暫時的,希望能有更好的 SQL。

然后必須將數據與許多其他表連接才能獲得最終產品。 但是我仍然需要處理最初的一組不同的數據。 從一開始就加入另一張桌子是行不通的。

所以這就是我如何提取數據、存儲它,然后稍后再提取它並將其連接到其他表:

INSERT INTO tmp_Person (Id, `Name`, Job, `Position`) 
    SELECT DISTINCT Id, `Name`, Job, `Position`
    FROM Person 

SELECT  tmp_Person.Id, 
    tmp_Person.`Name`, 
    tmp_Person.Job, 
    tmp_Person.`Position`,
    Pricing.Cost, 
    Pricing.Benefit

    FROM tmp_Person
    LEFT OUTER JOIN Pricing AS CL ON CL.PersonId = tmp_Person.Id 
        AND CL.PriceScredule = 'Major-Client' 
        AND CL.ExpireDate = '0000-00-00 00:00:00'
    LEFT OUTER JOIN Pricing AS Inter ON Inter.PersonId = tmp_Person.Id 
        AND Inter.PriceScredule = 'Internal-Client' 
        AND Inter.ExpireDate = '0000-00-00 00:00:00'

我怎樣才能寫這個來避免使用臨時表(以任何形式)處理重復行的成本? 希望我已經說得很清楚了,如果不是,我可以很高興地補充或澄清。

用臨時表的代碼替換tmp_Person

SELECT  tmp_Person.Id, 
    tmp_Person.`Name`, 
    tmp_Person.Job, 
    tmp_Person.`Position`,
    CL.Cost     AS MajorCost,              
    CL.Benefit  AS MajorBenefit,   
    Inter.Cost    AS InternalCost,
    Inter.Benefit AS InternalBenefit

    FROM 
      ( SELECT DISTINCT Id, `Name`, Job, `Position`
        FROM Person 
      )
      AS tmp_Person
    LEFT OUTER JOIN Pricing AS CL ON CL.PersonId = tmp_Person.Id 
        AND CL.PriceScredule = 'Major-Client' 
        AND CL.ExpireDate = '0000-00-00 00:00:00'
    LEFT OUTER JOIN Pricing AS Inter ON Inter.PersonId = tmp_Person.Id 
        AND Inter.PriceScredule = 'Internal-Client' 
        AND Inter.ExpireDate = '0000-00-00 00:00:00'

正如@Andriy 所發現的,在 SELECT 列表中使用Pricing.CostPricing.Benefit會引發錯誤。 我猜你發帖的時候忘記改了。

在我意識到問題是針對 mysql 之前將這些放在一起,但主體應該是相同的,這將為您提供每個 PersonID 的記錄以及來自 Person 表的最新 ActiveDate。

select *
from
(
 select persons.*, ROW_NUMBER() over(partition by personid order by personid, activedate desc) as rn 
 from persons
) basedata
where basedata.rn=1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM