1

I have 3 tables

Table1 (a view) contains the record ID, Person's Name, Attribute ID and a new record for all attributes entered into the database pertaining to the person.

Table2 is a descriptive identifier name for the Attribute Type ID in Table1

Table3 (a view) contains the data entry timestamp for the record ID in Table1, used as selection criteria range

Table1 --SQL Server 2014 View--

ID [char(18)]
Name [nvarchar(50)]
AttributeTypeID [int]
AttributeValue [nvarchar(2000)]

Table2 --SQL Server 2014 Table--

AttrTypeID [int]
AttrName [nvarchar(50)]

Table3 --SQL Server 2014 View--

EntryID [char(18)]
EntryDateTime [datetime2(3)]

My current query brings them together (however I would like a different output):

SELECT DISTINCT
Table1.ID
Table1.Name
Table2.AttrTypeID
Table2.AttrName
Table1.AttributeValue

FROM 
Table1 RIGHT JOIN Table2 ON Table1.AttributeTypeID = Table2.AttrTypeID

WHERE
Table1.ID IN (SELECT DISTINCT
             EntryID
             FROM Table3
             WHERE
             EntryDateTime BETWEEN '2018-05-01 00:00:00.000' AND '2018-05-07 00:00:00.000')

ORDER BY
Table1.ID ASC

Returns the following records:

ID     | Name  | AttrTypeID  | AttrName   | AttributeValue
123456 | Bob   | 201         | Hair Color | Blonde
123456 | Bob   | 202         | Eye Color  | Blue
123456 | Bob   | 203         | Height CM  | 180   
123456 | Bob   | 204         | Weight KG  | 77.1   
123456 | Bob   | 205         | Email      | bob@domain.com   
123456 | Bob   | 206         | Profile    | Text...2000characters...  
789000 | Sarah | 201         | Hair Color | Brown
789000 | Sarah | 202         | Eye Color  | Brown
789000 | Sarah | 203         | Height CM  | 155   
789000 | Sarah | 204         | Weight KG  | 50.5  
789000 | Sarah | 206         | Profile    | Text...2000characters...  

Note Sarah does not have an entry for email (AttrTypeID = 205) in table 1

My desired output is create a query that returns:

ID     | Name  | Hair Color  | Eye Color  | Height CM  | Weight KG  | Email           | Profile
123456 | Bob   | Blonde      | Blue       | 180        | 77.1       | bob@domain.com  | Text...2000characters...
789000 | Sarah | Brown       | Brown      | 155        | 50.5       | NULL            | Text...2000characters...

Your assistance is very much appreciated!

PS I'm new here so if you need more info or require a different format for asking this question please let me know.

  • 4
    You'll get faster help if you provide sample data as create table/inserts so people can jump right in and work with it. – Erik Darling May 8 '18 at 17:54
  • 1
    Second that comment by @sp_BlitzErik - your question doesn't appear trivial and it would be a lot of work to prepare a fiddle on our own - plus if, say, both Erik and I decided to try, we would be duplicating effort with the attendant risk of errors &c. – Vérace May 8 '18 at 18:11
  • 1
    Thanks gentlemen, I agree with this feedback, I will submit future questions with this in mind! I see I have an answer below and your assistance is greatly appreciated! – AlwaysLearning May 8 '18 at 18:31
0

Here is a very simple way to solve this.

--Setup demo data
Declare @Table1 table
    (ID int, Name varchar(5), AttrTypeID int, AttrName varchar(10), AttributeValue varchar(24))
;

INSERT INTO @Table1
    (ID, Name, AttrTypeID, AttrName, AttributeValue)
VALUES
    (123456, 'Bob', 201, 'Hair Color', 'Blonde'),
    (123456, 'Bob', 202, 'Eye Color', 'Blue'),
    (123456, 'Bob', 203, 'Height CM', '180'),
    (123456, 'Bob', 204, 'Weight KG', '77.1'),
    (123456, 'Bob', 205, 'Email', 'bob@domain.com'),
    (123456, 'Bob', 206, 'Profile', 'Text...2000characters...'),
    (789000, 'Sarah', 201, 'Hair Color', 'Brown'),
    (789000, 'Sarah', 202, 'Eye Color', 'Brown'),
    (789000, 'Sarah', 203, 'Height CM', '155'),
    (789000, 'Sarah', 204, 'Weight KG', '50.5'),
    (789000, 'Sarah', 206, 'Profile', 'Text...2000characters...')
;

--The actual query
SELECT ID, max(name) as Name,
  MAX(CASE WHEN AttrName = 'Hair Color' THEN AttributeValue END) AS [Hair Color],
  MAX(CASE WHEN AttrName = 'Eye Color' THEN AttributeValue END) AS [Eye Color],
  MAX(CASE WHEN AttrName = 'Height CM' THEN AttributeValue END) AS [Height CM],
  MAX(CASE WHEN AttrName = 'Weight KG' THEN AttributeValue END) AS [Weight KG],
  MAX(CASE WHEN AttrName = 'Email' THEN AttributeValue END) AS [Email],
  MAX(CASE WHEN AttrName = 'Profile' THEN AttributeValue END) AS [Profile]
FROM @Table1
GROUP BY id, name;

| ID     | Name  | Hair Color | Eye Color | Height CM | Weight KG | Email          | Profile                  |
|--------|-------|------------|-----------|-----------|-----------|----------------|--------------------------|
| 123456 | Bob   | Blonde     | Blue      | 180       | 77.1      | bob@domain.com | Text...2000characters... |
| 789000 | Sarah | Brown      | Brown     | 155       | 50.5      | NULL           | Text...2000characters... |

You just need to wrap your original query inside a common table expression and use that in place of my @Table1. Something like:

;With Table1 as
(
SELECT DISTINCT Table1.ID Table1.NAME Table2.AttrTypeID Table2.AttrName Table1.AttributeValue
FROM Table1
RIGHT JOIN Table2 ON Table1.AttributeTypeID = Table2.AttrTypeID
WHERE Table1.ID IN (
        SELECT DISTINCT EntryID
        FROM Table3
        WHERE EntryDateTime BETWEEN '2018-05-01 00:00:00.000'
                AND '2018-05-07 00:00:00.000'
        )
) 

--The actual query
SELECT ID, max(name) as Name,
  MAX(CASE WHEN AttrName = 'Hair Color' THEN AttributeValue END) AS [Hair Color],
  MAX(CASE WHEN AttrName = 'Eye Color' THEN AttributeValue END) AS [Eye Color],
  MAX(CASE WHEN AttrName = 'Height CM' THEN AttributeValue END) AS [Height CM],
  MAX(CASE WHEN AttrName = 'Weight KG' THEN AttributeValue END) AS [Weight KG],
  MAX(CASE WHEN AttrName = 'Email' THEN AttributeValue END) AS [Email],
  MAX(CASE WHEN AttrName = 'Profile' THEN AttributeValue END) AS [Profile]
FROM Table1
GROUP BY id, name;
  • If you think I have sufficiently answered your question, consider accepting it. – Scott Hodgin May 9 '18 at 9:10
  • I did accept it and thank you for your help! it said because I don't have enough history here I can't upvote or something – AlwaysLearning May 31 '18 at 22:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.