MySQL 具有单个 UNIQUE 约束指示符的列名
MySQL column name with singl UNIQUE constraint indicator
我需要一个查询(对于给定的 table 名称)如果此列存在 UNIQUE 约束但仅当此列是 SINGLE COLUMN 约束时显示带有指示符的列列表,而不是如果此列是多列约束的一部分。
例如 table:
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
您不应该只检查是否存在这样的约束,还应该检查该约束是否只有一列。因此 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
解决方法是:
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
我需要一个查询(对于给定的 table 名称)如果此列存在 UNIQUE 约束但仅当此列是 SINGLE COLUMN 约束时显示带有指示符的列列表,而不是如果此列是多列约束的一部分。
例如 table:
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
您不应该只检查是否存在这样的约束,还应该检查该约束是否只有一列。因此 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
解决方法是:
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