Question

I am working on an application where the user enters their name, age, state of residence. We want to capture the state to use for various things. Very straight forward when only one name, age, state of residence is listed. In some cases the user may list more than one name, age, state of residence. All of the data is stored in one table called Table. There is an ID, Name, and Value Column. I am attempting to pivot the data and then select the State of residence I need. There are two scenarios I need to account for.

-There are multiple names, ages, states of residence entered on the application. The state of residence we want is the one with the highest age. i.e.

Name    Age       State of Residence
John      25         FL
Bill      31         AL
Sue       26         MS

In scenario 1 I want to return AL as the State of Residence

-There are multiple names, ages, states of residence entered on the application. If the ages are the same in multiple states of residence, return the state that falls first alphabetically.

Name    Age       State of Residence
John      25         FL
Will      25         CA
Sue       26         MS

In scenario 2 I want to return CA as the State of Residence

I have tried:

Select State, Age
FROM (
            Select * from Table
            where ID = @ID and Name IN (State,Age)
     ) as s
PIVOT
(
            MAX(value) FOR Name IN (State,Age)
) as pvt

This returns the data, I just lack the knowledge on how to get the rest of the way. I tried adding group by but it would not work with the PIVOT.

I also tried it this way:

DECLARE @State AS NVARCHAR(2)
SELECT 
[State],[ [Acres]
INTO #tmpTable FROM Table
PIVOT
(
MAX(Value)
FOR [Name]
IN ([State],[Acres])AS p
WHERE ID = @ID
--
SELECT * FROM #tmpTable
-- 
DROP TABLE #tmpTable

Edited/Updated information: I have one table called dbo.Table with ID,NAME,VALUE,INSTANCE columns. In the first scenario, the table looks like this after the user enters two different records:

ID      NAME         VALUE      INSTANCE
1000    FIRST NAME   JOHN          1
1000    AGE          25            1
1000    STATE        AZ            1
1000    FIRST NAME   BILL          2
1000    AGE          27            2
1000    STATE        NH            2

I want to return NH as the State of Residence becuase it has the higest age.

In the second scenario the table looks like:

ID      NAME        VALUE       INSTANCE
1000    FIRST NAME  JOHN           1
1000    AGE         25             1
1000    STATE       AZ             1
1000    FIRST NAME  BILL           2
1000    AGE         25             2
1000    STATE       NH             2

I want to return AZ as the State of Residence because it falls first alphabetically

I am accounting for both scenarios. Neither is guaranteed to occur. The user may only enter one record. Either way a State of Residence is always returned. I hope that makes more sense. I attempted to pivot the data as you see it above, but do not understand how to get the state i need. Thanks.

Was it helpful?

Solution

Edited

Ok. I got the point. You're suffering from a bad designed table. It is not at least in 1FN where each table column (attribute) cannot store more than a single value from a single domain. In your case you have a widespread table, accepting any kind of attribute you want. The best option to you is fix your columns in a common 1FN table, like:

CREATE TABLE dbo.table (
    instance INTEGER ... ,
    first_name VARCHAR... ,
    age integer... ,
    state CHAR(2)...
)

Anyways, if you're working with legacy applications that you cannot modify, try this out:

-- Create a database VIEW to simulate a 1FN table
CREATE VIEW dbo.view1 AS
SELECT DISTINCT
    t.INSTANCE,
    (
    SELECT
        t2.value
    FROM
        dbo.table t2
    WHERE
            t2.id = t.id
        AND t2.instance = t.instance
        AND t2.name = 'FIRST NAME'
    ) AS FIRST_NAME,
    (
    SELECT
        t2.value
    FROM
        dbo.table t2
    WHERE
            t2.id = t.id
        AND t2.instance = t.instance
        AND t2.name = 'AGE'
    ) AS AGE,
    (
    SELECT
        t2.value
    FROM
        dbo.table t2
    WHERE
            t2.id = t.id
        AND t2.instance = t.instance
        AND t2.name = 'STATE'
    ) AS STATE
FROM
    dbo.table t

Then...

Question 1 - although all fields are selected you can fetch only state if you want

SELECT
    *
FROM
    dbo.view1 v
WHERE
    v.age = (
        SELECT
            MAX(v2.age)
        FROM
            dbo.view1 v2
    )

Question 2 - First state according to alphabetical order ascending

SELECT
    MIN(v.state) AS state
FROM
    dbo.view1 v
WHERE
    -- you can define a WHERE condition to meet your requirements here
    v.age = 25

If you like it, please upvote this answer or mark it as acceptable :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top