I have this select statement to return number of rows between two dates. It only returns one while while there are foure rows.
SELECT count(*) as number
FROM PFServicesLogging
WHERE User_ID = '784198013531599'
AND ServiceType = 1
AND InsertDate between "2013-11-11" and "2013-11-19"
table structure is
CREATE TABLE `PFServicesLogging`
(
ID INTEGER NOT NULL,
ServiceType INTEGER NOT NULL,
Datetime DATETIME,
User_ID TEXT,
Frequency INTEGER, `InsertDate` Date,
PRIMARY KEY(ID)
)
If your date fields include the time of day, do not use between. Use
where YourDateField >= StartDate
and YourDateField < TheDayAfterTheEndDate
Edit Starts Here
Reading the comments, maybe the problem has nothing to do with the dates. Maybe it's the user_id or service type. To troubleshoot, replace your where clause with
where 1 = 1
/*
User_ID = '784198013531599'
AND ServiceType = 1
AND InsertDate between "2013-11-11" and "2013-11-19"
*/
and run your query. Take your filters out of the comment block one by one so that you can see which one causes the unexpected results.
Related
I have the following sqllite table:
CREATE TABLE test (
id INTEGER NOT NULL,
date TEXT,
account TEXT,
........
value TEXT,
.......
PRIMARY KEY (id),
CONSTRAINT composite UNIQUE (date, account)
)
I want to find all the account numbers where the value is greater than 0 on 2 separate dates . I'm thinking:
SELECT * from test WHERE value> 0 GROUP BY account
is probably a start, but I don't know how to evaluate the size of groups
One way to phrase this query is to aggregate over accounts having a greater than zero value, and then retain those accounts having two or more distinct dates:
SELECT
account
FROM test
WHERE value > 0
GROUP BY account
HAVING COUNT(DISTINCT date) >= 2
I see that your value column is declared as TEXT. I think this should probably be an integer if you want to do numeric comparisons with this column.
I'm actually beginner in SQL and i working on Oracle engine. I have a problem to do arithmetic manipulation using Interval, to add on timestamp column - integer value, that exist in other table and convert it to Minute.
To test my schemas i used in data generator. As a result, Some of the data produced, are not reliable and i need to check overlapping between two appointments, when the same patient invited for two treatments overlap.
I have treatments_appointments table that contains these attributes:
treatments_appointments(app_id NUMBER(38) NOT NULL,
[fk] care_id NUMBER(38) NOT NULL,
[fk] doctor_id NUMBER(38) NOT NULL,
[fk] room_id NUMBER(38) NOT NULL,
[fk] branch_id NUMBER(38) NOT NULL,
[fk] patient_id NUMBER(38) NOT NULL,
appointment_time TIMESTAMP NOT NULL)
Below is the code what i wrote and it's get an error message:
SELECT app1.app_id
FROM treatment_appointment app1
INNER JOIN treatment_appointment app2
ON app1.patient_id = app2.patient_id
WHERE app1.appointment_time >= app2.appointment_time AND
app1.appointment_time <=
app2.appointment_time + interval (to_char(select care_categories.care_duration where app2.care_id = care_categories.care_id)) minute
AND
app1.app_id != app2.app_id
The error message is:
ORA-00936: missing expression
Sorry about my English and thanks for answering my question!
You can only use a fixed string value for an INTERVAL literal, not a variable, an expression or a column value. But you can use the NUMTODSINTERVAL function to convert a number of minutes into an interval. Instead of:
interval (to_char(select care_categories.care_duration
where app2.care_id = care_categories.care_id)) minute
Use:
numtodsinterval(select care_categories.care_duration
where app2.care_id = care_categories.care_id, 'MINUTE')
Although you should join to that table in the main query rather than doing a subquery for every row:
SELECT app1.app_id
FROM treatment_appointment app1
INNER JOIN treatment_appointment app2
ON app1.patient_id = app2.patient_id
INNER JOIN care_categories cc
ON app2.care_id = cc.care_id
WHERE app1.appointment_time >= app2.appointment_time AND
app1.appointment_time <=
app2.appointment_time + numtodsinterval(cc.care_duration, 'MINUTE') AND
app1.app_id != app2.app_id
I've got a .Net application with an attendance table which has fields for a Start and End date. I'm struggling to show a graph of attendance for a given period. I can easily find how many rows are applicable on any given day using between but I can't get my head around pivoting results so that I can graph a count of rows per day. I could run a SQL query for every day individually and then graph the results but is there any way of doing this with T-SQL that I could then use to graph with?
Edit:-
Apologies as this is the first time I've asked a question here, but as huMpty duMpty has stated the question probably needs more clarification. I've got both a startdate and enddate column in the sql db and I need to count per day if the range between these dates falls between the range of the selection criteria. e.g if I've got a start date of 2013-01-01 and end date 2013-01-10 and I report on a period of 2013-01-09 to 2013-01-11 then i'm looking at getting a result for 1 for 2013-01-09 and 1 for 2013-01-10... Hope this make more sense and thanks for your assistance
I think you have a table with start and end dates; for a given date range, you would like to know the given number of records that fall on each date.
I believe this problem may be solved with a numbers table. I created a numbers table on the fly in a stored procedure, but I recommend creating a permanent numbers table in your production code. Here's the SQL Fiddle.
Create Table Attendance (
id int primary key identity(1,1) not null
,start_date date not null
,end_date date not null
);
Go
Insert Attendance(start_date, end_date)
Values ('1/1/2013', '1/10/2013')
,('1/10/2013', '1/15/2013')
,('2/20/2013', '3/1/2013');
Go
-- Create numbers table. See: Method 3 of http://stackoverflow.com/a/1407488/772086
With Numbers(Number) As
(
Select 1 As Number
Union All
Select Number + 1 From Numbers Where Number < 10000
)
Select
AttendanceDate = Convert(date, DateAdd(day,Numbers.number, '1/1/2000'))
,AttendanceCount = Count(*)
From dbo.Attendance
Join Numbers
On Numbers.Number
Between DateDiff(day, '1/1/2000', Attendance.start_date)
And DateDiff(day, '1/1/2000', Attendance.end_date)
-- Reporting range between 1/9 and 1/11
Where DateAdd(day,Numbers.number, '1/1/2000') Between '1/9/2013'
And '1/11/2013'
Group By Convert(date, DateAdd(day,Numbers.number, '1/1/2000'))
Option(MaxRecursion 10000);
All dates are in US format (m/d/yy) - you may want to switch those to the internationalized standard (yyyy-mm-dd) in your production code.
You said you wanted a count by day in a date range. That can be done with a COUNT with a GROUP BY clause.
I don't know your schema, but a solution might look like this:
declare #MyTable table
(
ID int identity(1,1) primary key clustered,
MyDate smalldatetime
)
insert into #MyTable (MyDate)
values
('2012-12-31'), -- before the date range, so not included in results
('2013-01-10'),
('2013-01-10'), -- appears twice
('2013-01-11'), -- appears once
('2013-01-12') -- after the date range, so not included in results
select * from #MyTable
select
MyDate,
count(*)
from #MyTable
where MyDate between '2013-01-09' and '2013-01-11'
group by MyDate
I am working on a project that is using JDBC (Derby driver), The part of the table details are provided below.
Table Name : Example (
RID Char(5) Primary Key
RTime TIME NOT NULL,
RDate Date NOT NULL
)
I know how to find the closest date to current date (or time) using MAX, but in WHERE condition, MAX and MIN definitely do not work in most SQL.
How can I find the date/time nearest to current date/time in Derby db?
You could either do it with a subquery
SELECT * FROM T WHERE RTime = (SELECT MAX(RTime) FROM T) AND RDate = ...
or by sorting on the RDate and RTime columns and selecting the first.
Lets frame the question again---
table1{date, bID, sName, fID}
{11/05,B1,A1,P1}
{12/05,B2,A2,P2}
{13/05,B1,A3,P1}
{15/05,B3,A4,P1}
{16/05,B1,A5,P2}
{19/05,B1,A6,P2}
This is the table and the data stored in the table is also specified...
Now the query that i want is that:-
Depending of fId (lets say, P1 is selected) it should display the data from table say from 11/05-17/05 (no date should be missed). The data retrieved is as follows:-
11/05,B1,A1
12/05,--,--
13/05,B1,A3
14/05,--,--
15/05,B3,A4
16/05,--,--
17/05,--,--
The data retrieved for a particular fID(say P1) is displayed.. Explaning the result...
1) it displayed all data from 11/05-17/05 where fId is P1, if there is no date in the database, then also it should display null value for that date (i.e.14/05 date was not there in database, but still it displayed with a null value)..
2) if fId for that particular date is not P1, then also it store a null value in result set..
Atlast the data is retrieved in result set,, and processed further..
So i want to write the query for this problemm,, is it possible..
No code here, just my thoughts.
You need to create a temporary table with dates ranging from your begin date to an end date, inclusive. And then left join table1 with that temporary table on date column plus add where fID = ?.
As the other answer here mentions, a table with all the dates in it, and a LEFT JOIN is what you need.
Say you have this table:
CREATE TABLE table1
{
date DATETIME
bID VARCHAR(10),
sName VARCHAR(10),
fID VARCHAR(10)
}
and then this date-table:
CREATE TABLE dates
(
dt DATETIME
)
and in this table you need to have all the dates for the range you want to display. Usually you populate it with a couple of years in both directions, but that's up to you.
Note: For simplicity, I did not bother with primary keys in either table. You should of course make sure you have a primary key, and in the case of the dates table, it could be the dt column.
Then to display the results you want:
SELECT
dt,
bID,
sName
FROM
dates
LEFT JOIN table1 ON dt = date AND fld = 'P1'
ORDER BY
dt
Note that the selection of only P1 rows is done in the JOIN criteria. If you add a WHERE clause to do the same, you'll loose all dates that have no data.