2017-12-12 11 views
1

この列のUNIQUE制約が存在する場合は、(指定された表名に対して)インジケータ付き列のリストを表示する必要があります。ただし、この列がSINGLE COLUMN制約の場合のみこの列は複数の列制約の一部です。このテーブルの例singl UNIQUE制約インジケータを持つMySQLの列名

CREATE TABLE IF NOT EXISTS `prices` (
    `priceId` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `motorcycleId` INT UNSIGNED NOT NULL, 
    `priceDatum` DATE NOT NULL, 
    `price` INT NOT NULL DEFAULT 0, 
    PRIMARY KEY (`priceId`), 
    INDEX `price_motorcycleId_fk_idx` (`motorcycleId` ASC), 
    UNIQUE INDEX `priceId_UNIQUE` (`priceId` ASC), 
    UNIQUE INDEX `price_UNIQUE` (`motorcycleId` ASC, `priceDatum` ASC), 
    CONSTRAINT `price_motorcycleId_fk` 
    FOREIGN KEY (`motorcycleId`) 
    REFERENCES `motorcycles` (`motorcycleId`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE) 
ENGINE = InnoDB; 

このクエリは与える必要があります。そのような制約が存在する場合

COLUMN  |UNIQUE 
============+====== 
priceId  | Y 
motorcycleId| N <-- should not be shown as UNIQUE since not single constraint 
priceDatum | N <-- should not be shown as UNIQUE since not single constraint 
price  | N 
+1

サイドノートでは、ユニーク制約は、priceIdに冗長です。 –

+1

あなたの注意のために@ Michael-sqlbotをありがとう、それは貴重です。私はこれが冗長であることを知っていますが、例のためにここに入れています。私は最近それについて議論していました(https://stackoverflow.com/questions/47493487/mysql-primary-key-vs-unique-constraintsをご覧ください) – sbrbot

答えて

0

ソリューションです:主キーが定義上一意であるため、

SELECT c.COLUMN_NAME, 
     IF((SELECT COUNT(k2.COLUMN_NAME) 
      FROM information_schema.KEY_COLUMN_USAGE k1 
      JOIN information_schema.KEY_COLUMN_USAGE k2 
       ON (k1.CONSTRAINT_NAME=k2.CONSTRAINT_NAME 
       AND k1.TABLE_NAME=k2.TABLE_NAME 
       AND k1.TABLE_SCHEMA=k2.TABLE_SCHEMA) 
      JOIN information_schema.TABLE_CONSTRAINTS tc 
       ON (k2.CONSTRAINT_NAME=tc.CONSTRAINT_NAME 
       AND k2.TABLE_NAME=tc.TABLE_NAME 
       AND k2.TABLE_SCHEMA=tc.TABLE_SCHEMA 
       AND tc.CONSTRAINT_TYPE='UNIQUE') 
     WHERE k1.COLUMN_NAME=c.COLUMN_NAME 
      AND k1.TABLE_NAME=c.TABLE_NAME)=1,'Y','N') AS `UNIQUE` 
    FROM information_schema.COLUMNS c 
    LEFT JOIN information_schema.KEY_COLUMN_USAGE k 
    ON (k.TABLE_SCHEMA=c.TABLE_SCHEMA 
     AND k.TABLE_NAME=c.TABLE_NAME 
     AND k.COLUMN_NAME=c.COLUMN_NAME 
     AND k.POSITION_IN_UNIQUE_CONSTRAINT IS NOT NULL) 
WHERE c.TABLE_NAME='prices' 
ORDER BY c.ORDINAL_POSITION 
0

は、あなただけのチェックではないはずですが、また、その制約は1列のみを持っている場合。 KEY_COLUMN_USAGEの制約の数は1にする必要があります。

私は現時点ではテストできませんが、このような制約を持つ列を取得するには、次のようになります。サブクエリでも同様のことができます。または、すべての列のリストにこのクエリを結合してチェックするだけです。レコードが存在する場合は、一意の単一列制約があります。

select 
    k.COLUMN_NAME 
from 
    information_schema.KEY_COLUMN_USAGE k 
    join information_schema.TABLE_CONSTRAINTS tc 
    on k.TABLE_SCHEMA = tc.TABLE_SCHEMA 
     and k.TABLE_NAME = tc.TABLE_NAME 
     and k.CONSTRAINT_NAME = tc.CONSTRAINT_NAME 
where 
    k.TABLE_NAME = 'prices' 
    and tc.CONSTRAINT_TYPE = 'UNIQUE' 
group by 
    k.CONSTRAINT_CATALOG, 
    k.CONSTRAINT_SCHEMA, 
    k.CONSTRAINT_NAME 
having 
    count(*) = 1 
+0

あなたの努力のために@GolezTrolに感謝します。私はHAVING COUNT(*)= 1でほぼ同じことを試みましたが、成功しませんでした。サブクエリは機能しません。ここではSQLFiddle http://sqlfiddle.com/#!9/cbe483/17私はそれをやったが、私はそれが最善のアプローチかどうかわからない。それでもGROUP BY HAVINGでこれを行うことができ、1つのJOINの内部SELECTを減らすことができると考えています。 – sbrbot

関連する問題