how to use clause(where,and,not) sql - mysql

I have table absen like this:
and the table itungharian with coloumn like this:
id_itung | id | total | itungtgl
(no data)
and query join like this:
SELECT
count(tgl) AS total,
absen.id,
pegawai.nama,
pegawai.bagian,
pegawai.bagian,
pegawai.tglmasuk,
gaji.jenis_gaji,
gaji.jumlah,
itungharian.id AS id2,
itungharian.itungtgl,
CASE
WHEN (weekday(tgl) <=3 )
THEN date(tgl + INTERVAL(3 - weekday(tgl)) DAY)
ELSE date(tgl + INTERVAL(3 + 7 - weekday(tgl)) DAY)
END AS tglitung
FROM
absen
JOIN
pegawai ON pegawai.id = absen.id
JOIN
gaji ON gaji.id = pegawai.id
LEFT JOIN
itungharian ON itungharian.id = absen.id
WHERE
absen.status = 'm'
GROUP BY
absen.id,
tglitung
and show this
So I have problem how to join like this if values on cloumn id(table absen) same with itungharian.tgl and tglitung(result case when) same with itungharian.itungtgl don't show in join table
I have tried with sql like this:
SELECT
count(tgl) AS total,
absen.id,
pegawai.nama,
pegawai.bagian,
pegawai.bagian,
pegawai.tglmasuk,
gaji.jenis_gaji,
gaji.jumlah,
itungharian.id AS id2,
itungharian.itungtgl,
CASE
WHEN (weekday(tgl) <= 3)
THEN date(tgl + INTERVAL(3 - weekday(tgl)) DAY)
ELSE date(tgl + INTERVAL(3 + 7 - weekday(tgl)) DAY)
END AS tglitung
FROM
absen
JOIN
pegawai ON pegawai.id = absen.id
JOIN
gaji ON gaji.id = pegawai.id
LEFT JOIN
itungharian ON itungharian.id = absen.id
WHERE
absen.status = 'm'
AND
NOT (CASE WHEN (weekday(tgl) <= 3)
THEN DATE(tgl + INTERVAL(3 - weekday(tgl)) DAY)
ELSE DATE(tgl + INTERVAL(3 + 7 - weekday(tgl)) DAY)END) = itungharian.itungtgl
AND
NOT absen.id = itungharian.id
GROUP BY
absen.id,
tglitung
but MySQL returned an empty result set (i.e. zero rows).

Related

Where do I put the sum function to sum sick leave days in this query?

The query shown below gives me the number of leave days excluding Saturday and Sunday. My problem is I don't know where to put the sum() function to sum all leave days.
SELECT DATEDIFF(eleave.resume_date , eleave.leave_date) as total_days , (
ABS(DATEDIFF(eleave.leave_date, eleave.resume_date)) -
ABS(DATEDIFF(ADDDATE(eleave.leave_date, INTERVAL 1 -
DAYOFWEEK(eleave.leave_date) DAY) , ADDDATE(eleave.resume_date, INTERVAL
1 - DAYOFWEEK(eleave.resume_date) DAY))) / 7 * 2 -
(DAYOFWEEK(IF(eleave.resume_date < eleave.leave_date , leave.resume_date,
eleave.leave_date)) = 1) - (DAYOFWEEK(IF(eleave.resume_date >
eleave.leave_date, eleave.resume_date, eleave.leave_date)) = 7)) as
leavedays , employee.emp_lname , type.typ_name as leavetype ,
education.qualification , education.program FROM employee INNER JOIN eleave on employee.emp_num = eleave.emp_num LEFT JOIN type ON type.typ_id =
eleave.typ_id left join education ON employee.emp_num = education.emp_num
WHERE employee.emp_num = 4774 AND type.typ_name = 'Sick leave'
You should do the sum per employee to get total leaves for each employee
it will look like this
SELECT employee.emp_num,
SUM (ABS(DATEDIFF(eleave.leave_date, eleave.resume_date)) - ABS(DATEDIFF(ADDDATE(eleave.leave_date, INTERVAL 1 - DAYOFWEEK(eleave.leave_date) DAY) , ADDDATE(eleave.resume_date, INTERVAL 1 - DAYOFWEEK(eleave.resume_date) DAY))) / 7 * 2 - (DAYOFWEEK(IF(eleave.resume_date < eleave.leave_date , leave.resume_date, eleave.leave_date)) = 1) - (DAYOFWEEK(IF(eleave.resume_date > eleave.leave_date, eleave.resume_date, eleave.leave_date)) = 7)) as leavedays
FROM employee INNER JOIN eleave on employee.emp_num = eleave.emp_num
LEFT JOIN type ON type.typ_id = eleave.typ_id left join education
ON employee.emp_num = education.emp_num
WHERE employee.emp_num = 4774 AND type.typ_name = 'Sick leave'
GROUP BY employee.emp_num

SQL where query to a first row of IN condition

I have this SQL query:
SELECT (CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END) as availability
FROM (
SELECT count(roomTypeDay2.room_type_id) as _days
FROM room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
WHERE roomType2.accommodation_id=3
AND roomTypeDay2.date IN ( '2018-06-09 00:00:00','2018-06-10 00:00:00','2018-06-11 00:00:00')
GROUP BY roomTypeDay2.room_type_id
HAVING COUNT(roomTypeDay2.room_type_id) = 3
) as disponible
This works fine, but now, I want to filter if the first date row (2018-06-09 00:00:00) have
"min_night_stay <= 3 and release_days <=2"
parameters, but I don't know how doing it.
I try adding these lines to a query:
AND (roomTypeDay2.date = '2018-06-09 00:00:00' and
roomTypeDay2.min_night_stay <= 3 AND roomTypeDay2.release_days <= 2)
But this is not correct query.
UDPATE
SELECT (CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END) as availability
FROM (
SELECT count(roomTypeDay2.room_type_id) as _days
FROM room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
AND roomType2.accommodation_id=3
WHERE roomTypeDay2.date IN ( '2018-06-09 00:00:00','2018-06-10 00:00:00','2018-06-11 00:00:00')
GROUP BY roomTypeDay2.room_type_id
HAVING COUNT(roomTypeDay2.room_type_id) = 3
) as disponible
Solution
SELECT (CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END) as availability
FROM (
SELECT count(roomTypeDay2.room_type_id) as _days
FROM room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
WHERE roomType2.accommodation_id=3
AND roomTypeDay2.num_rooms_available > 0
AND (roomTypeDay2.date = '2018-06-12 00:00:00' AND roomTypeDay2.min_night_stay <= 2 AND roomTypeDay2.release_days <= 2 )
OR roomTypeDay2.date IN ( '2018-06-13 00:00:00','2018-06-14 00:00:00')
GROUP BY roomTypeDay2.room_type_id
HAVING COUNT(roomTypeDay2.room_type_id) = 3
) as disponible
This is your WHERE clause:
WHERE roomTypeDay2.date IN ('2018-06-09 00:00:00',
'2018-06-10 00:00:00',
'2018-06-11 00:00:00')
Now for the first date you want additional criteria. Use AND and ORwith parentheses for this:
WHERE
(
roomTypeDay2.date = '2018-06-09 00:00:00'
AND
roomTypeDay2.min_night_stay <= 3
AND
roomTypeDay2.release_days <= 2
)
OR
roomTypeDay2.date IN ('2018-06-10 00:00:00','2018-06-11 00:00:00')
SELECT
(
CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END
) as availability
from
(
SELECT
count(roomTypeDay2.room_type_id) as _days
FROM
room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
AND roomType2.accommodation_id = 3
WHERE
roomTypeDay2.date IN ('2018-06-10 00:00:00', '2018-06-11 00:00:00')
GROUP BY
roomTypeDay2.room_type_id
HAVING
COUNT(roomTypeDay2.room_type_id) = 3
union
SELECT
count(roomTypeDay2.room_type_id) as _days
FROM
room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
AND roomType2.accommodation_id = 3
WHERE
roomTypeDay2.date = '2018-06-09 00:00:00'
and roomTypeDay2.min_night_stay <= 3
AND roomTypeDay2.release_days <= 2
GROUP BY
roomTypeDay2.room_type_id
HAVING
COUNT(roomTypeDay2.room_type_id) = 3
) disponible

EMBEDDED DATEDIFF EXCLUD WEEKENDS + CASE STATEMENT

I have the below query that utilizes a case statement. I would like to datediff two dates but exclude weekend days.
I have the below that excutes but now I would like to exclude Sat and Sunday from this... AND DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) <= 2
CASE WHEN
S.Name IN ('Assessment','Survey')
AND A.ALERT_DESC = 'ER'
AND CAST(A.ALERTS_CREATE_DT AS DATE) <= CAST(S.CreatedDate AS DATE)
AND DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) <= 2 /*EXCLUDE Sat and Sunday from the calculation*/
Full Query
SELECT
CASE WHEN
S.Name IN ('Assessment','Survey')
AND A.ALERT_DESC = 'ER'
AND CAST(A.ALERTS_CREATE_DT AS DATE) <= CAST(S.CreatedDate AS DATE)
AND
( DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) <= 2 /*Business Days*/
--DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate) + 1
---(DATEDIFF(WK,A.ALERTS_CREATE_DT,S.CreatedDate) * 2)
---(CASE WHEN DATENAME(DW,A.ALERTS_CREATE_DT) = 'SUNDAY' THEN 1 ELSE 0 END)
---(CASE WHEN DATENAME(DW,S.CreatedDate) = 'SATURADAY' THEN 1 ELSE 0 END)
)
THEN 'Y'
WHEN A.ALERT_DESC = 'model' OR S.CreatedDate IS NULL OR S.Name = 'ER'
THEN ''
ELSE 'N'
END 'Count towards Alerts'
FROM A
FULL S ON A.id= S.id
WHERE 1=1
This should give you the required result by excluding the Saturdays and Sundays.
SELECT A.ALERT_DESC,A.ALERTS_CREATE_DT,S.Name,S.CreatedDate,
CASE WHEN
S.Name IN ('Assessment','Survey') AND A.ALERT_DESC = 'ER'
AND CAST(A.ALERTS_CREATE_DT AS DATE) <= CAST(S.CreatedDate AS DATE)
AND
(( DATEDIFF(DD,A.ALERTS_CREATE_DT,S.CreatedDate)+1
- (datediff(wk,A.ALERTS_CREATE_DT,S.CreatedDate)*2)
- case when datepart(dw,A.ALERTS_CREATE_DT)=1 then 1 else 0 end
- case when datepart(dw,S.CreatedDate)=7 then 1 else 0 end
)) <=2 THEN 'Y'
WHEN A.ALERT_DESC = 'model' OR S.CreatedDate IS NULL OR S.Name = 'ER' THEN ''
ELSE 'N' END 'Count towards Alerts'
FROM A,S

sql query with DISTINCT make huge performance issue

i have a query to get summary of donations
SELECT CONVERT(CHAR(2), CAST(pb.PayrollDate AS DATETIME), 101)
+ '/' + CONVERT(CHAR(4), CAST(pb.PayrollDate AS DATETIME), 120) AS Closing_Month ,
CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112) AS Closing_Year ,
COUNT(DISTINCT Donation.Employee) + ( SELECT COUNT(*)
FROM dbo.Donation
INNER JOIN PayrollBatch pbd ON Donation.PayrollBatch = pbd.ID
WHERE CONVERT(CHAR(6), CAST(pbd.PayrollDate AS DATETIME), 112) = CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112)
AND DonationType = 5
)AS 'Donors' ,
COUNT (DISTINCT( CASE WHEN Donation.DonationType = 1 OR Donation.DonationType = 5 THEN CharityDetails.ID
END ))AS 'Charities',
( CAST(COUNT(DISTINCT Donation.Employee) AS DECIMAL(18, 2))
/ ( SELECT SUM(NumberOfEmployees)
FROM OrganisationDetail
WHERE ID = Donation.OrganisationDetail
AND IsDeleted = 0
) ) * 100 AS 'Participation_Rate' ,
SUM(CASE WHEN Donation.DonationType = 1 OR Donation.DonationType = 5 THEN Donation.Amount
ELSE 0
END) AS 'Employee_Donations' ,
SUM(CASE WHEN Donation.DonationType = 2 THEN Donation.Amount
ELSE 0
END) AS 'Matched_Donations' ,
SUM(CASE WHEN Donation.DonationType = 1
OR Donation.DonationType = 2 OR Donation.DonationType = 5 THEN Donation.Amount
ELSE 0
END) AS 'Total_Donations'
FROM Donation
INNER JOIN OrganisationDetail AS OrganisationDetail_1 ON Donation.OrganisationDetail = OrganisationDetail_1.ID
INNER JOIN CharityProjectDetails ON Donation.CharityProjectDetails = CharityProjectDetails.ID
INNER JOIN CharityDetails ON CharityProjectDetails.CharityDetails = CharityDetails.ID
INNER JOIN PayrollBatch pb ON Donation.PayrollBatch = pb.ID
LEFT JOIN Employee ON Donation.Employee = Employee.ID
LEFT JOIN DonationIntent ON Donation.DonationIntent = DonationIntent.ID
LEFT JOIN EmployeeAddress ON Employee.ID = EmployeeAddress.Employee
LEFT JOIN dbo.PayrollBatchOther pbo ON pbo.PayrollBatch = pb.ID
GROUP BY CONVERT(CHAR(2), CAST(pb.PayrollDate AS DATETIME), 101)
+ '/' + CONVERT(CHAR(4), CAST(pb.PayrollDate AS DATETIME), 120) ,
CONVERT(CHAR(6), CAST(pb.PayrollDate AS DATETIME), 112) ,
Donation.OrganisationDetail
ORDER BY Closing_Year;
i need to get unique donors count from result set COUNT(DISTINCT e.ID) but with distinct query takes 7-9 sec to complete execution but without that it took only 1 sec how to improve that performance
Update
Here is the Paste The Plan

Unknown column sql query (solve)

I have table absen with clause join, where and group
and I have this query
SELECT count( tgl ) AS total,
absen.id, pegawai.nama, pegawai.bagian,
pegawai.bagian, pegawai.tglmasuk, gaji.jenis_gaji,
gaji.jumlah, gajiharian.id_gajiharian,
gajiharian.status, gajiharian.tgldigaji,
CASE WHEN (weekday( tgl ) <=3)
THEN date( tgl + INTERVAL( 3 - weekday( tgl ) ) DAY )
ELSE date( tgl + INTERVAL( 3 +7 - weekday( tgl ) ) DAY )
END AS tglitung
FROM absen
JOIN pegawai ON pegawai.id = absen.id
JOIN gaji ON gaji.id = pegawai.id
LEFT JOIN gajiharian ON gajiharian.id = absen.id
WHERE absen.status = 'm'
AND absen.id = '15'
AND tglitung='2016-01-14'
GROUP BY absen.id, tglitung
and results in
#1054 - Unknown column 'tglitung' in 'where clause'
How do I solve that?
I want 'as tglitung' can detect as column.