Sql - How to Get The Unique Key's Column Name from Table

SQL - How to get the Unique Key's Column Name from Table

Something like this might work (untested):

SELECT *
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
WHERE TC.TABLE_NAME = 'MYTABLENAME'
AND TC.CONSTRAINT_TYPE = 'UNIQUE'

SQL Query - Latest Row of Each Unique Column Name

Assuming you're using Timestamp as the row creation time, just get it by max ID.

Here is a solution not using a window function:

SELECT Y.*
FROM
(
SELECT MaxID = MAX(ID)
FROM MyTable
GROUP BY Category
) AS X
INNER JOIN MyTable AS Y ON
Y.ID = X.MaxID

Select unique column names from a list of joined tables

This script generate dynamic SQL for any table with similar PK name.

Query:

SET NOCOUNT ON

IF OBJECT_ID (N'dbo.A') IS NOT NULL
DROP TABLE dbo.A

IF OBJECT_ID (N'dbo.B') IS NOT NULL
DROP TABLE dbo.B

IF OBJECT_ID (N'dbo.C') IS NOT NULL
DROP TABLE dbo.C

CREATE TABLE dbo.A (PK_field INT PRIMARY KEY, column1 INT, column2 INT)
CREATE TABLE dbo.B (PK_field INT PRIMARY KEY, column3 INT, column4 INT)
CREATE TABLE dbo.C (PK_field INT PRIMARY KEY, column5 INT, [column 6] INT)

INSERT INTO dbo.A (PK_field, column1, column2)
VALUES (1, 1, 2), (2, 1, 2)

INSERT INTO dbo.B (PK_field, column3, column4)
VALUES (2, 3, 4)

INSERT INTO dbo.C (PK_field, column5, [column 6])
VALUES (1, 5, 6), (3, 5, 6)

DECLARE @SQL NVARCHAR(MAX)

;WITH cte AS
(
SELECT
column_name = '[' + c.name + ']'
, table_name = '[' + s.name + '].[' + o.name + ']'
FROM sys.columns c WITH (NOLOCK)
JOIN sys.objects o WITH (NOLOCK) ON c.[object_id] = o.[object_id]
JOIN sys.schemas s WITH (NOLOCK) ON o.[schema_id] = s.[schema_id]
WHERE o.name IN ('A', 'B', 'C')
AND s.name = 'dbo'
AND o.[type] = 'U'
), unicol AS (
SELECT TOP 1 column_name
FROM cte
GROUP BY cte.column_name
HAVING COUNT(cte.column_name) > 1
), cols AS
(
SELECT DISTINCT column_name
FROM cte
), tbl AS
(
SELECT DISTINCT table_name
FROM cte
), rs AS
(
SELECT
tbl.table_name
, column_name = ISNULL(cte.column_name, cols.column_name + ' = NULL')
FROM cols
CROSS JOIN tbl
LEFT JOIN cte ON cols.column_name = cte.column_name AND cte.table_name = tbl.table_name
), rs2 AS (
SELECT uni = ' UNION ALL' + CHAR(13) + 'SELECT ' + STUFF((
SELECT ', ' + rs.column_name
FROM rs
WHERE tbl.table_name = rs.table_name
GROUP BY rs.column_name
ORDER BY rs.column_name
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') +
' FROM ' + table_name
FROM tbl
)
SELECT @SQL = 'SELECT
' + STUFF((
SELECT CHAR(13) + ', ' + ISNULL(unicol.column_name, cols.column_name + ' = MAX(' + cols.column_name + ')')
FROM cols
LEFT JOIN unicol ON cols.column_name = unicol.column_name
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, ' ')
+ '
FROM
(' + STUFF((
SELECT CHAR(10) + uni
FROM rs2
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 11, '') + CHAR(13) +
') t
GROUP BY ' + (SELECT column_name FROM unicol)

PRINT @SQL

EXECUTE sys.sp_executesql @SQL

Output:

SELECT 
[column 6] = MAX([column 6])
, [column1] = MAX([column1])
, [column2] = MAX([column2])
, [column3] = MAX([column3])
, [column4] = MAX([column4])
, [column5] = MAX([column5])
, [PK_field]
FROM (
SELECT [column 6] = NULL, [column1], [column2], [column3] = NULL, [column4] = NULL, [column5] = NULL, [PK_field] FROM [dbo].[A]
UNION ALL
SELECT [column 6] = NULL, [column1] = NULL, [column2] = NULL, [column3], [column4], [column5] = NULL, [PK_field] FROM [dbo].[B]
UNION ALL
SELECT [column 6], [column1] = NULL, [column2] = NULL, [column3] = NULL, [column4] = NULL, [column5], [PK_field] FROM [dbo].[C]
) t
GROUP BY [PK_field]

Results:

column 6    column1     column2     column3     column4     column5     PK_field
----------- ----------- ----------- ----------- ----------- ----------- -----------
6 1 2 NULL NULL 5 1
NULL 1 2 3 4 NULL 2
6 NULL NULL NULL NULL 5 3

Update in script:

DECLARE @SQL NVARCHAR(2000) -> NVARCHAR(MAX)

Output for your DDL:

SELECT 
[blaiseKey_code]
, [bDEM_BOP_q1stParentBornNZ] = MAX([bDEM_BOP_q1stParentBornNZ])
, [bDEM_BOP_q2ndParentBornNZ] = MAX([bDEM_BOP_q2ndParentBornNZ])
, [bDEM_BOP_qHowManyParentBornNZ] = MAX([bDEM_BOP_qHowManyParentBornNZ])
, [bDEM_BOP_qHowManyRaised] = MAX([bDEM_BOP_qHowManyRaised])
, [bDEM_WOR_q2Jobs1HrsIntro] = MAX([bDEM_WOR_q2Jobs1HrsIntro])
, [bDEM_WOR_q2Jobs2HrsIntro] = MAX([bDEM_WOR_q2Jobs2HrsIntro])
, [bDEM_WOR_q2JobsNoHrsIntro] = MAX([bDEM_WOR_q2JobsNoHrsIntro])
, [bDEM_WOR_qEmployArrangement] = MAX([bDEM_WOR_qEmployArrangement])
, [bDEM_WOR_qFeelAboutJob] = MAX([bDEM_WOR_qFeelAboutJob])
, [bDEM_WOR_qJobsNum] = MAX([bDEM_WOR_qJobsNum])
, [bDEM_WOR_qJobsNumNR] = MAX([bDEM_WOR_qJobsNumNR])
, [bDEM_WOR_qMainTasks] = MAX([bDEM_WOR_qMainTasks])
, [bDEM_WOR_qMainTasksNR] = MAX([bDEM_WOR_qMainTasksNR])
, [bDEM_WOR_qOccupation] = MAX([bDEM_WOR_qOccupation])
, [bDEM_WOR_qOccupationNR] = MAX([bDEM_WOR_qOccupationNR])
, [bDEM_WOR_qPaidWorkIntro] = MAX([bDEM_WOR_qPaidWorkIntro])
, [bDEM_WOR_qPermEmployee] = MAX([bDEM_WOR_qPermEmployee])
, [bDEM_WOR_tabDEM_T2_fTotMins] = MAX([bDEM_WOR_tabDEM_T2_fTotMins])
, [fCountryName] = MAX([fCountryName])
, [q3MthsStudy] = MAX([q3MthsStudy])
, [qAge] = MAX([qAge])
, [qAge15OrOver] = MAX([qAge15OrOver])
, [qAgeNR] = MAX([qAgeNR])
, [qAgeRange] = MAX([qAgeRange])
, [qArriveNZMth] = MAX([qArriveNZMth])
, [qArriveNZYr] = MAX([qArriveNZYr])
, [qArriveNZYrNR] = MAX([qArriveNZYrNR])
, [qAwayFromWork] = MAX([qAwayFromWork])
, [qBornInNZ] = MAX([qBornInNZ])
, [qCouldStartLastWk] = MAX([qCouldStartLastWk])
, [qCountryOfBirth] = MAX([qCountryOfBirth])
, [qDidPaidWork] = MAX([qDidPaidWork])
, [qDOB] = MAX([qDOB])
, [qDOBNR] = MAX([qDOBNR])
, [qFamilyBusWork] = MAX([qFamilyBusWork])
, [qHasJobToStart] = MAX([qHasJobToStart])
, [qHighestQual] = MAX([qHighestQual])
, [qHighestQualOth] = MAX([qHighestQualOth])
, [qHighestQualOthNR] = MAX([qHighestQualOthNR])
, [qHighestQualYr] = MAX([qHighestQualYr])
, [qHighestQualYrNR] = MAX([qHighestQualYrNR])
, [qIncTotalAmt] = MAX([qIncTotalAmt])
, [qJobSearchA] = MAX([qJobSearchA])
, [qJobSearchB] = MAX([qJobSearchB])
, [qJobSearchC] = MAX([qJobSearchC])
, [qJobSearchD] = MAX([qJobSearchD])
, [qJobSearchE] = MAX([qJobSearchE])
, [qJobSearchF] = MAX([qJobSearchF])
, [qJobSearchG] = MAX([qJobSearchG])
, [qJobSearchH] = MAX([qJobSearchH])
, [qJobSearchI] = MAX([qJobSearchI])
, [qJobSearchOth] = MAX([qJobSearchOth])
, [qJobSearchOthNR] = MAX([qJobSearchOthNR])
, [qLookedForWork] = MAX([qLookedForWork])
, [qMaoriDescent] = MAX([qMaoriDescent])
, [qNotEligible] = MAX([qNotEligible])
, [qPostSchQual] = MAX([qPostSchQual])
, [qSchQual] = MAX([qSchQual])
, [qSchQualOth] = MAX([qSchQualOth])
, [qSchQualOthNR] = MAX([qSchQualOthNR])
, [qSchQualYr] = MAX([qSchQualYr])
, [qSchQualYrNR] = MAX([qSchQualYrNR])
, [qSex] = MAX([qSex])
, [qThingsWorthwhileScale] = MAX([qThingsWorthwhileScale])
, [qWorkIntro] = MAX([qWorkIntro])
FROM
(
SELECT [bDEM_BOP_q1stParentBornNZ], [bDEM_BOP_q2ndParentBornNZ], [bDEM_BOP_qHowManyParentBornNZ], [bDEM_BOP_qHowManyRaised], [bDEM_WOR_q2Jobs1HrsIntro], [bDEM_WOR_q2Jobs2HrsIntro], [bDEM_WOR_q2JobsNoHrsIntro], [bDEM_WOR_qEmployArrangement], [bDEM_WOR_qFeelAboutJob], [bDEM_WOR_qJobsNum], [bDEM_WOR_qJobsNumNR], [bDEM_WOR_qMainTasks], [bDEM_WOR_qMainTasksNR], [bDEM_WOR_qOccupation], [bDEM_WOR_qOccupationNR], [bDEM_WOR_qPaidWorkIntro], [bDEM_WOR_qPermEmployee], [bDEM_WOR_tabDEM_T2_fTotMins], [blaiseKey_code], [fCountryName], [q3MthsStudy], [qAge], [qAge15OrOver], [qAgeNR], [qAgeRange], [qArriveNZMth], [qArriveNZYr], [qArriveNZYrNR], [qAwayFromWork], [qBornInNZ], [qCouldStartLastWk], [qCountryOfBirth], [qDidPaidWork], [qDOB], [qDOBNR], [qFamilyBusWork], [qHasJobToStart], [qHighestQual], [qHighestQualOth], [qHighestQualOthNR], [qHighestQualYr], [qHighestQualYrNR], [qIncTotalAmt], [qJobSearchA], [qJobSearchB], [qJobSearchC], [qJobSearchD], [qJobSearchE], [qJobSearchF], [qJobSearchG], [qJobSearchH], [qJobSearchI], [qJobSearchOth], [qJobSearchOthNR], [qLookedForWork], [qMaoriDescent], [qNotEligible], [qPostSchQual], [qSchQual], [qSchQualOth], [qSchQualOthNR], [qSchQualYr], [qSchQualYrNR], [qSex], [qThingsWorthwhileScale] = NULL, [qWorkIntro] FROM [dbo].[G_bDEM]
UNION ALL
SELECT [bDEM_BOP_q1stParentBornNZ] = NULL, [bDEM_BOP_q2ndParentBornNZ] = NULL, [bDEM_BOP_qHowManyParentBornNZ] = NULL, [bDEM_BOP_qHowManyRaised] = NULL, [bDEM_WOR_q2Jobs1HrsIntro] = NULL, [bDEM_WOR_q2Jobs2HrsIntro] = NULL, [bDEM_WOR_q2JobsNoHrsIntro] = NULL, [bDEM_WOR_qEmployArrangement] = NULL, [bDEM_WOR_qFeelAboutJob] = NULL, [bDEM_WOR_qJobsNum] = NULL, [bDEM_WOR_qJobsNumNR] = NULL, [bDEM_WOR_qMainTasks] = NULL, [bDEM_WOR_qMainTasksNR] = NULL, [bDEM_WOR_qOccupation] = NULL, [bDEM_WOR_qOccupationNR] = NULL, [bDEM_WOR_qPaidWorkIntro] = NULL, [bDEM_WOR_qPermEmployee] = NULL, [bDEM_WOR_tabDEM_T2_fTotMins] = NULL, [blaiseKey_code], [fCountryName] = NULL, [q3MthsStudy] = NULL, [qAge] = NULL, [qAge15OrOver] = NULL, [qAgeNR] = NULL, [qAgeRange] = NULL, [qArriveNZMth] = NULL, [qArriveNZYr] = NULL, [qArriveNZYrNR] = NULL, [qAwayFromWork] = NULL, [qBornInNZ] = NULL, [qCouldStartLastWk] = NULL, [qCountryOfBirth] = NULL, [qDidPaidWork] = NULL, [qDOB] = NULL, [qDOBNR] = NULL, [qFamilyBusWork] = NULL, [qHasJobToStart] = NULL, [qHighestQual] = NULL, [qHighestQualOth] = NULL, [qHighestQualOthNR] = NULL, [qHighestQualYr] = NULL, [qHighestQualYrNR] = NULL, [qIncTotalAmt] = NULL, [qJobSearchA] = NULL, [qJobSearchB] = NULL, [qJobSearchC] = NULL, [qJobSearchD] = NULL, [qJobSearchE] = NULL, [qJobSearchF] = NULL, [qJobSearchG] = NULL, [qJobSearchH] = NULL, [qJobSearchI] = NULL, [qJobSearchOth] = NULL, [qJobSearchOthNR] = NULL, [qLookedForWork] = NULL, [qMaoriDescent] = NULL, [qNotEligible] = NULL, [qPostSchQual] = NULL, [qSchQual] = NULL, [qSchQualOth] = NULL, [qSchQualOthNR] = NULL, [qSchQualYr] = NULL, [qSchQualYrNR] = NULL, [qSex] = NULL, [qThingsWorthwhileScale], [qWorkIntro] = NULL FROM [dbo].[G_bLWW]
) t
GROUP BY [blaiseKey_code]

How to retrieve all keys along with their column names and table name of particular schema in postgresql 9.5?

To see basic table details

SELECT * 
FROM information_schema.columns
WHERE table_name = 'yourTableName';

To list out all FORIEN KEY,PRIMARY KEY, UNIQUE KEY constraints

SELECT tc.constraint_name,
tc.constraint_type,
tc.table_name,
kcu.column_name,
tc.is_deferrable,
tc.initially_deferred,
rc.match_option AS match_type,

rc.update_rule AS on_update,
rc.delete_rule AS on_delete,
ccu.table_name AS references_table,
ccu.column_name AS references_field
FROM information_schema.table_constraints tc

LEFT JOIN information_schema.key_column_usage kcu
ON tc.constraint_catalog = kcu.constraint_catalog
AND tc.constraint_schema = kcu.constraint_schema
AND tc.constraint_name = kcu.constraint_name

LEFT JOIN information_schema.referential_constraints rc
ON tc.constraint_catalog = rc.constraint_catalog
AND tc.constraint_schema = rc.constraint_schema
AND tc.constraint_name = rc.constraint_name

LEFT JOIN information_schema.constraint_column_usage ccu
ON rc.unique_constraint_catalog = ccu.constraint_catalog
AND rc.unique_constraint_schema = ccu.constraint_schema
AND rc.unique_constraint_name = ccu.constraint_name

WHERE lower(tc.constraint_type) in ('foreign key')

Using of unique column name for each primary and foreign keys in mysql table to avoid ambiguous condition

Naming conventions are up to you. Which naming convention you decide to use is not important. What's important is that you follow your own convention consistently, and document it so that other developers know how to understand your code and your schema.

Some people choose to give every table a primary key named id. If every one of their tables must have a column named id, then they can write reusable code for certain queries against any table.

However, this convention does not account for compound primary keys. Also if your query does a join, the query result set may have multiple columns named id unless you define column aliases.

When I design a database, I name my primary key in a descriptive way. projects.project_id for example. This avoids the problem of duplicate column names in a result set of a join. It also makes it more clear what the column means when you see it in a query or a result set.

I like to name the foreign key the same as the primary key column it references, when I can do it without resulting in a conflict.

But consider this example, where there are multiple foreign keys in the same table that reference Users.user_id.

CREATE TABLE Bugs (
bug_id INT PRIMARY KEY,
description TEXT NOT NULL,
reported_date DATETIME NOT NULL,
user_reported_by INT NOT NULL,
user_assigned_to INT,
user_verified_by INT,
FOREIGN KEY (user_reported_by) REFERENCES Users(user_id),
FOREIGN KEY (user_assigned_to) REFERENCES Users(user_id),
FOREIGN KEY (user_verified_by) REFERENCES Users(user_id)
);

You can't assume you can use a common column name, because it's normal to need multiple foreign keys referencing the same table, as in the example above. Therefore you must allow the FK column name to be different from the PK it references.

How to find out whether a table has some unique columns

Here's an approach that is basically similar to @JNK's but instead of printing the counts it returns a ready answer for every column that tells you whether a column consists of unique values only or not:

DECLARE @table varchar(100), @sql varchar(max);
SET @table = 'some table name';

SELECT
@sql = COALESCE(@sql + ', ', '') + ColumnExpression
FROM (
SELECT
ColumnExpression =
'CASE COUNT(DISTINCT ' + COLUMN_NAME + ') ' +
'WHEN COUNT(*) THEN ''UNIQUE'' ' +
'ELSE '''' ' +
'END AS ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table
) s

SET @sql = 'SELECT ' + @sql + ' FROM ' + @table;
PRINT @sql; /* in case you want to have a look at the resulting query */
EXEC(@sql);

It simply compares COUNT(DISTINCT column) with COUNT(*) for every column. The result will be a table with a single row, where every column will contain the value UNIQUE for those columns that do not have duplicates, and empty string if duplicates are present.

But the above solution will work correctly only for those columns that do not have NULLs. It should be noted that SQL Server does not ignore NULLs when you want to create a unique constraint/index on a column. If a column contains just one NULL and all other values are unique, you can still create a unique constraint on the column (you cannot make it a primary key, though, which requires both uniquness of values and absence of NULLs).

Therefore you might need a more thorough analysis of the contents, which you could get with the following script:

DECLARE @table varchar(100), @sql varchar(max);
SET @table = 'some table name';

SELECT
@sql = COALESCE(@sql + ', ', '') + ColumnExpression
FROM (
SELECT
ColumnExpression =
'CASE COUNT(DISTINCT ' + COLUMN_NAME + ') ' +
'WHEN COUNT(*) THEN ''UNIQUE'' ' +
'WHEN COUNT(*) - 1 THEN ' +
'CASE COUNT(DISTINCT ' + COLUMN_NAME + ') ' +
'WHEN COUNT(' + COLUMN_NAME + ') THEN ''UNIQUE WITH SINGLE NULL'' ' +
'ELSE '''' ' +
'END ' +
'WHEN COUNT(' + COLUMN_NAME + ') THEN ''UNIQUE with NULLs'' ' +
'ELSE '''' ' +
'END AS ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table
) s

SET @sql = 'SELECT ' + @sql + ' FROM ' + @table;
PRINT @sql; /* in case you still want to have a look at the resulting query */
EXEC(@sql);

This solution takes NULLs into account by checking three values: COUNT(DISTINCT column), COUNT(column) and COUNT(*). It displays the results similarly to the former solution, but the possible diagnoses for the columns are more diverse:

  • UNIQUE means no duplicate values and no NULLs (can either be a PK or have a unique constraint/index);

  • UNIQUE WITH SINGLE NULL – as can be guessed, no duplicates, but there's one NULL (cannot be a PK, but can have a unique constraint/index);

  • UNIQUE with NULLs – no duplicates, two or more NULLs (in case you are on SQL Server 2008, you could have a conditional unique index for non-NULL values only);

  • empty string – there are duplicates, possibly NULLs too.



Related Topics



Leave a reply



Submit