Solved

sql querying selected columns.... non normalized table

Posted on 2002-04-16
4
492 Views
Last Modified: 2008-02-26
Hi,
My table structure was designed as follows :

Field Name--->  Empno, Day1, Day2, Day3 ... Day30
Type      --->  (Int), Int,  Int,  Int, ... Int

assumption : Day1 = 1st day of the month
             Day2 = 2nd day of the month ...etc.

The query :
based on a given Date .... select only the required columns (Day? ... Day?)

for example :
   Input Date = 10th Jan.  to   12th Jan.

   the result set should be :
   Empno, Day10, Day11, Day12.

can this be done using SQL ?
any suggestions?


Note : If I normalized the table, it would solve all the problems .. but, I can't change the existing table structure, unfortunately.

Thanks.
0
Comment
Question by:llkhor
  • 2
4 Comments
 
LVL 22

Expert Comment

by:DrSQL
ID: 6946721
llkhor,

   It depends on your RDBMS.  Most have a CASE function and some means of converting dates so that you can get the day of the month.  I'll use Oracle's to_char function to get the day of the month and select a case statement.

For a single date:

select empno,
case
  when to_char(InputDate, 'DD') = '01' then Day1
  when to_char(InputDate, 'DD') = '02' then Day2
  when to_char(InputDate, 'DD') = '03' then Day3
  when to_char(InputDate, 'DD') = '04' then Day4
  when to_char(InputDate, 'DD') = '05' then Day5
  when to_char(InputDate, 'DD') = '06' then Day6
  when to_char(InputDate, 'DD') = '07' then Day7
  when to_char(InputDate, 'DD') = '08' then Day8
  when to_char(InputDate, 'DD') = '09' then Day9
...
  when to_char(InputDate, 'DD') = '30' then Day30
  else Day31 end as DayInfo
from myTable;


If you want a date range, it would be similar, just a more complex condition.  And you'd need two inputs - "10th Jan.  to   12th Jan" isn't going to be understood too well.  Here's an example:

select empno,
case
  when '01' between to_char(InputStartDate, 'DD')
                  and to_char(InputEndDate, 'DD') then Day1

  when '01' between to_char(InputStartDate, 'DD')
                  and to_char(InputEndDate, 'DD') then Day2
  when '01' between to_char(InputStartDate, 'DD')
                  and to_char(InputEndDate, 'DD') then Day3
  when '01' between to_char(InputStartDate, 'DD')
                  and to_char(InputEndDate, 'DD') then Day4
...
  when '01' between to_char(InputStartDate, 'DD')
                 and to_char(InputEndDate, 'DD') then Day30
  else Day31 end as DayInfo
from myTable;


Good luck!

0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6947001
brrrrrrr . . . .
0
 
LVL 22

Accepted Solution

by:
DrSQL earned 50 total points
ID: 6947755
llkhor,
   The solution I gave only works for a single column.  My second statement would only return the FIRST day that met the condition.  In order to return multiple columns you can do one of two things:

1) Decide on the maximum number of returns that you will allow and set up a case for each one.  You'll always return that many columns, even if you make the case return a null when there's no column (less than the maximum).

2) Return multiple rows - one for each date in the range - and "flatten" them into a single row via a join.  This also requires knowing how many you want to return.

It might be best to handle this in logic - either dynamically generate the select and execute it, or return multiple records and grab the values.  In order to return multiple records you need a "LOOPER" table.  This table has a column called SEQ and it has (for this example) the numbers 1 - 31 inserted as records.  Then, you would:

select empno,
case
 when looper.seq = 1 then Day1
 when looper.seq = 2 then then Day2
 when looper.seq = 3 then then Day3
 when looper.seq = 4 then then Day4
...
 when looper.seq = 3' then Day30
 else Day31 end as DayInfo
from myTable, looper
where looper.seq between
              to_number(to_char(InputStartDate, 'DD'))
          and to_number(to_char(InputEndDate, 'DD'));

In your example, this would give you three records.  How you would flatten them in SQL would depend on your RDBMS.  In Oracle, I'd use the rank() function:

select one.empno, one.dayinfo, two.dayinfo, three.dayinfo
from
(select empno,
case
 when looper.seq = 1 then Day1
 when looper.seq = 2 then then Day2
 when looper.seq = 3 then then Day3
 when looper.seq = 4 then then Day4
...
 when looper.seq = 3' then Day30
 else Day31 end as DayInfo,
 rank() over (order by looper.seq) as ranking
from myTable, looper
where looper.seq between
              to_number(to_char(InputStartDate, 'DD'))
          and to_number(to_char(InputEndDate, 'DD'))) one,
(<exactly the same SQL>) two,
(<same again>) three
where one.empno=two.empno and
      one.empno=three.empno and
      one.ranking = 1 and two.ranking=2 and three.ranking=3;

As you can see - messy and requires foreknowledge of how many returns.

I guess it means that the short answer to your question is no.  But, you can come close.

Sorry to add to any confusion (and draw any undeserved cool points).

Good luck!

0
 

Author Comment

by:llkhor
ID: 6949545
DrSQL,

first of all, thanks.

I'm using desktop database (Paradox - Delphi environment), which doesn't support Case or Rank.

I'd thought of 'normalizing' the table by generating a temp table (as you pointed out in option 2) and flatten it out with 'join'.  

Then again, I don't have to use SQL statement to do it .....direct table to table update handled by program logic will do.

I just wonder if it could be done with a single SQL statement.....

"I guess it means that the short answer to your question is no" .... I agreed.

Thanks.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Compare data between two databases 16 95
SQL QUERY to Table question 32 83
#deleted rowsc access 2010 backend 4 47
SQL BACKUP - 2008 R2 8 61
APEX (Application Express) is used to develop a web application from Oracle. SQL Workshop is one of the tools that comes with Oracle APEX to query or modify the database objects or to make any changes to the structure.
I annotated my article on ransomware somewhat extensively, but I keep adding new references and wanted to put a link to the reference library.  Despite all the reference tools I have on hand, it was not easy to find a way to do this easily. I finall…
Video by: Steve
Using examples as well as descriptions, step through each of the common simple join types, explaining differences in syntax, differences in expected outputs and showing how the queries run along with the actual outputs based upon a simple set of dem…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

912 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now