6

次のフィールド (特に) を持つ珍しい SQL テーブル (私のものではない) があります: last_name, primary_name, secondary_name、夫婦を示します。姓は共有されていると見なされ (あまり現代的ではないことはわかっています)、カップルでない場合は、 または のいずれかprimary_namesecondary_nameNULL になる可能性があります。(テーブルにはいくつかの重複もあります。)

私がやりたいことは、データベース内のすべての名前 (「最初と最後」) のリストを、通常の方法でアルファベット順に取得することです。現在、PHP と PDO を使用して、データベースを介して 2 つのパスを実行しています。

$qstr = "SELECT DISTINCT primary_name, last_name 
            FROM members 
            WHERE primary_name IS NOT null
            ORDER BY last_name, primary_name";
$sth = $dbh->prepare($qstr);
$sth->execute();
// output the results

$qstr = "SELECT DISTINCT secondary_name, last_name 
            FROM members 
            WHERE secondary_name IS NOT null
            ORDER BY last_name, secondary_name";
$sth = $dbh->prepare($qstr);
$sth->execute();
// output the new results

ただし、2 番目のパスが最初からやり直されるため、最終結果はアルファベット順ではありません。

すべての名前を一度に完全にアルファベット順に取得するにはどうすればよいですか? SQL でこれを行う方法はありますか、または 2 つの配列を作成し、後で PHP でそれらを再アルファベット化する必要がありますか?

編集 データベースは次のようになります。

last_name  primary_name   secondary_name
----------------------------------------
Abrams     Joe            Susan
Miller     Sam            Abby

望ましい出力は次のようになります。

["Joe Abrams","Susan Abrams","Abby Miller","Sam Miller"]

代わりに、最初のパスですべての夫を取得し、2 番目のパスですべての妻を取得すると、次のような結果が得られます。

["Joe Abrams","Sam Miller","Susan Abrams","Abby Miller"]
4

3 に答える 3

7

If I understand correctly, I think you are looking for something like this:

select distinct coalesce(primary_name, secondary_name) as pri_sec_name,
    last_name
from members
where coalesce(primary_name, secondary_name) is not null
order by last_name,
    coalesce(primary_name, secondary_name)

Update

It sounds like in some cases you have one row for a last_name, where both primary_name and secondary_name are populated. The query below should give you the output you want (sorry, no COALESCE this time):

select last_name, pri_sec_name
from (
    select primary_name as pri_sec_name, last_name from members where primary_name is not null
    union all
    select secondary_name as pri_sec_name, last_name from members where secondary_name is not null
) a 
order by last_name, pri_sec_name
于 2012-04-24T14:26:48.927 に答える
2

別の方法は、UNIONを使用することです...

SELECT
  *
FROM
(
  SELECT primary_name AS pri_sec_name, last_name 
    FROM members 
   WHERE primary_name IS NOT null

  UNION

  SELECT secondary_name AS pri_sec_name, last_name 
    FROM members 
   WHERE secondary_name IS NOT null
)
  AS data
ORDER BY
  last_name, pri_sec_name

注:( UNION ではなくUNION ALL結果の重複を排除します。

もう1つは、マッピングテーブルで結合を行うことです。

SELECT
  members.last_name,
  CASE WHEN map.mode = 1 THEN members.primary_name ELSE members.secondary_name END AS pri_sec_name
FROM
  members
INNER JOIN
  (SELECT 1 as mode UNION ALL SELECT 2 as mode) AS map
    ON (map.mode = 1 AND members.primary_name   IS NOT NULL)
    OR (map.mode = 2 AND members.secondary_name IS NOT NULL)
ORDER BY
  1,
  2
于 2012-04-24T14:45:32.213 に答える
2

私はあなたが必要だと思います:

SELECT primary_name AS name
     , last_name 
  FROM members 
  WHERE primary_name IS NOT NULL
UNION 
SELECT secondary_name
     , last_name 
  FROM members 
  WHERE secondary_name IS NOT NULL
ORDER BY last_name, name

別の書き換えは次を使用していUNION ALLます:

SELECT COALESCE(primary_name, secondary_name) AS name
     , last_name 
  FROM members 
UNION ALL
SELECT secondary_name
     , last_name 
  FROM members 
  WHERE primary_name IS NOT NULL
    AND secondary_name IS NOT NULL
ORDER BY last_name, name

2 番目のバージョンの方が高速かもしれませんが、重複した結果が表示される場合があります。さらに例を挙げると、次の行があり、1 つJoe Jacksonは と結婚しSusan、もう 1 つは と結婚していLeaます。

last_name  primary_name   secondary_name
----------------------------------------
Jackson    Joe            Susan
Jackson    Joe            Lea

最初のクエリは次のように表示されます。

name   last_name
-----------------
Joe    Jackson 
Lea    Jackson 
Susan  Jackson 

2番目には「重複」があります:

name   last_name
-----------------
Joe    Jackson 
Joe    Jackson 
Lea    Jackson 
Susan  Jackson 

どちらがより適切かは、仕様によって異なります。

于 2012-04-24T14:46:02.807 に答える