0

Table structure like this

select * from TimeTable;

        userid | 1am|2am|3am| 4am| 5am
        1002   | 1  |1  |1  | 1  | 1
        1003   | 1  |1  |1  | 1  | 1 
        1004   | 1  |1  |1  | 1  | 1
        1005   | 1  |1  |1  | 1  | 1

I want select users that have column value 1 of specific timecolumn I have used following query but it is throwing error

com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the varchar value '[ 3PM]' to data type int.

select * from UserDetail u,TimeTable t  
where u.userid=t.userid
and CONCAT(SUBSTRING(CONVERT(VARCHAR, getdate(), 100), 13, 2) ,'',RIGHT(CONVERT(VARCHAR, GETDATE(), 100),2)) = 1

Like this when I use hardcoded column name then it works fine I want to select a column name dynamically.

select * from UserDetail u,TimeTable t  
where u.userid = t.userid
and [3AM] = 1
7
  • 1
    Tip of today: Switch to modern explicit JOIN syntax. Easier to write (without errors), easier to read (and maintain), and easier to convert to outer join if needed. Commented Apr 4, 2018 at 10:52
  • Are you sure you are using MySQL? This looks like SQL Server syntax. Commented Apr 4, 2018 at 10:53
  • That CONCAT condition does no comparison. Commented Apr 4, 2018 at 10:53
  • you can't use the result of a subquery as a column name in SQL .. (you should use dinamic sql for this) .. Commented Apr 4, 2018 at 11:01
  • you can assign a column name to the result of a subquery, but not refer to it in the where clause of the same select statement, unless you repeat the same subquery there. I'd design the source query as a VIEW so I can refer to the subquery result column just like I would use a table column in the query that consumes the view. At the moment there is no subquery at all in your post, so please clarify that first. Commented Apr 4, 2018 at 11:03

3 Answers 3

1

Option 1

Use a long list of short-circuited WHERE clauses like below which seems fine given the table design and quite easy to understand

DECLARE @currentHour int = DATEPART(HOUR, getdate())
SELECT * FROM TimeTable
WHERE
    (@currentHour = 1 AND [1am] = 1) OR
    (@currentHour = 2 AND [2am] = 1) OR
    (@currentHour = 3 AND [3am] = 1) OR
    (@currentHour = 4 AND [4am] = 1) OR
    (@currentHour = 5 AND [5am] = 1) -- Etc

Option 2

Use UNPIVOT or VALUES to rotate the hour based columns into rows. As part of the rotate you can translate the column into a number indicating the hour. This you can compare with the current time’s hour component.

Option 3

Use dynamic sql which might or might not be ok for your environment or usage.

Below is the UNPIVOT approach (Option 2) which is a bit more complex to understand.

create table Test (id int, [1am] int, [2am] int, [3am] int, [4am] int)

insert Test values
  (1, 1, 2, 3, 4)
  , (2, 11, 12, 13, 14)
  , (3, 1, 21, 23, 24)
  , (4, 31, 32, 33, 34)

declare @time datetime = '2018-01-01 01:10:00' -- change this to getdate()

;WITH MatchingIds (id) AS
(
  SELECT id
  FROM
    (SELECT 
       id,  
       [1am] AS [1], [2am] AS [2], [3am] AS [3], [4am] AS [4] --etc 
     FROM Test) AS Source
     UNPIVOT
     (val FOR hour IN 
      ([1], [2], [3], [4]) --etc
     ) AS asRows
  WHERE 
      hour = CONVERT(VARCHAR, DATEPART(HOUR, @time)) 
      AND val = 1
) 
SELECT * FROM MatchingIds
-- MatchingIds now contains the rows that match your criteris
-- This can be joined with other tables to generate your full result

Intermediate output from MatchingIds for above example with time param set to around 1am

| id |
|----|
|  1 |
|  3 |

http://sqlfiddle.com/#!18/85c9c/5

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, This will help me to find a solution !!
0

Try:

select * from UserDetail u,TimeTable t  
where u.userid=t.userid
and 
(select COLUMN_NAME 
 from INFORMATION_SCHEMA.COLUMNS 
 where    TABLE_NAME = 'tblName' 
      AND TABLE_CATALOG = 'DBNAME'
      AND COLUMN_NAME = CONCAT(SUBSTRING(CONVERT(VARCHAR, getdate(), 100), 13, 2) ,'',RIGHT(CONVERT(VARCHAR, GETDATE(), 100),2))) = 1

Comments

0

select CONCAT(SUBSTRING(CONVERT(VARCHAR, getdate(), 100), 13, 2) ,'',RIGHT(CONVERT(VARCHAR, GETDATE(), 100),2)) is a value of type varchar, not the syntax of a query. What you are currently doing is for sql similar to:

select * from UserDetail u,TimeTable t  
where u.userid=t.userid
and '12PM' = 1

Even if parser accepted your query the condition would always be false as '12PM' is not the same as 12PM or [12PM]. You cannot dynamically modify a query within the query itself to make it work.

Yes, you could do tricks like dynamic execution (build entire query as string and then execute it), but please -don't. The real problem in you code is that you have a rather bad table design. Consider redesigning your TimeTable table to have timeOfDay values a single column and actual time values as data in that column. You'll save yourself a lot of headache later.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.