Problem with UNION result in Yii2 Framework - yii2

$select = (new yii\db\Query())
->select('autori.IDAutore, autori.IParte, autori.IIParte, autori.Prefisso, autori.Qualificazione, count(autori.IDAutore) AS qta')
->from('autori')->where('1=1')
->innerJoin('bibliografie b', '
b.RIDAutorePrinc1 = autori.IDAutore
')->limit(10)->orderby('COUNT(*) DESC');
$select1 = (new yii\db\Query())
->select('autori.IDAutore, autori.IParte, autori.IIParte, autori.Prefisso, autori.Qualificazione, count(autori.IDAutore) AS qta')
->from('autori')->where('1=1')
->innerJoin('bibliografie b', '
b.RIDAutorePrinc2 = autori.IDAutore
')->limit(10)->orderby('COUNT(*) DESC');
$select->union($select1);
$autoreList = $select->groupby('autori.IDAutore')->limit(10)->all();
This will return:
Michael (10)
Michael(4)
I want: Michael (14)
Which is the problem? Thank you

union return sperated rows .. so you have two values
coul be you need another join condition of a single query instead of a union between two queries
$select = (new yii\db\Query())
->select('autori.IDAutore
, autori.IParte
, autori.IIParte
, autori.Prefisso
, autori.Qualificazione
, count(autori.IDAutore) AS qta')
->from('autori')->where('1=1')
->innerJoin('bibliografie b', '
b.RIDAutorePrinc1 = autori.IDAutore OR b.RIDAutorePrinc2 = autori.IDAutore
')->limit(10)->orderby('COUNT(*) DESC');
if you have performance problem for a complex query you could try using pure sql and a sql command eg:
$connection = \Yii::$app->db;
$q = " select t.IDAutore
, t.IParte
, t.IIParte
, t.Prefisso
, t.Qualificazione
, sum( num_autori)
from (
select autori.IDAutore
, autori.IParte
, autori.IIParte
, autori.Prefisso
, autori.Qualificazione
, count(autori.IDAutore) num_autori
from autori
inner join bibliografie b on b.RIDAutorePrinc1 = autori.IDAutore
order by num_autori
limit 10
union
select autori.IDAutore
, autori.IParte
, autori.IIParte
, autori.Prefisso
, autori.Qualificazione
, count(autori.IDAutore) num_autori
from autori
inner join bibliografie b on b.RIDAutorePrinc2 = autori.IDAutore
order by num_autori
limit 10
union
....
.....
....
select autori.IDAutore
, autori.IParte
, autori.IIParte
, autori.Prefisso
, autori.Qualificazione
, count(autori.IDAutore) num_autori
from autori
inner join bibliografie b on b.RIDAutorePrinc2 = autori.IDAutore
order by num_autori
limit 10 ) t
group by t.IDAutore
, t.IParte
, t.IIParte
, t.Prefisso
, t.Qualificazione"
$autoreListArray = $connection->createCommand($q)->queryAll();
$autoreListArray is an array with resulting list aggreagted by autore and with the sum of the single count in each select

Related

Convert SQL query to Eloquent Laravel with many join

How do I convert this query to Eloquent syntax
select *
from
( select f85
, f86
, f87
, f88
, v1_position_id
, v1_companyuser_id
, v89.position_value f89
from
( select f85
, f86
, f87
, v1_position_id
, v1_companyuser_id
, v88.position_value f88
from
( select f85
, f86
, v1_position_id
, v1_companyuser_id
, v87.position_value f87
from
( select f85
, v1_position_id
, v1_companyuser_id
, v86.position_value f86
from
( SELECT v1.position_id v1_position_id
, v1.companyuser_id v1_companyuser_id
, v1.position_value f85
FROM all_position_template_with_data v1
WHERE v1.position_id = 25
AND companyuser_id = 1
AND position_template_id = 85
) v1
join all_position_template_with_data v86
on v1_position_id = v86.position_id
AND v1_companyuser_id = v86.companyuser_id
AND v86.position_template_id = 86
) v86
join all_position_template_with_data v87
on v1_position_id = v87.position_id
AND v1_companyuser_id = v87.companyuser_id
AND v87.position_template_id = 87
) v87
join all_position_template_with_data v88
on v1_position_id = v88.position_id
AND v1_companyuser_id = v88.companyuser_id
AND v88.position_template_id = 88
) v88
join all_position_template_with_data v89
on v1_position_id = v89.position_id
AND v1_companyuser_id = v89.companyuser_id
AND v89.position_template_id = 89
) v89

Combining Two SQL Select Queries with Where Clauses

I have two Oracle queries that I need combined through an inner join where the tables are joined using the person_uid field. This is because I need to compare what an employee's pay, job title, and supervisor was from one year to the next. I need to have the 2015 data and the 2014 data in the same row for each employee, so if this can be done by doing a subquery using an inner join on the person_uid field, that is the method that I believe will accomplish this.
Here is the first query that pulls the necessary 2015 data:
SELECT person_uid,
id ,
position_contract_type,
position,
job_suffix,
position_status,
effective_date,
position_employee_class,
timesheet_organization ,
appointment_pct ,
annual_salary ,
per_pay_salary ,
hourly_rate ,
position_title ,
academic_title ,
supervisor_id ,
supervisor_name ,
supervisor_position ,
supervisor_job_suffix ,
supervisor_title ,
assignment_grade ,
position_change_reason ,
position_change_reason_desc
FROM employee_position_cunm posn
WHERE posn.position_contract_type = 'P'
AND posn.position_status <> 'T'
AND posn.effective_date = (SELECT MAX(effective_date)
FROM employee_position_cunm p2
WHERE p2.person_uid = posn.person_uid
AND p2.position = posn.position
AND p2.job_suffix = posn.job_suffix
AND p2.effective_date <= '01-Nov-2015')
order by person_uid
I need it to be joined to this query on the person_uid field so that each unique ID for the employee has the records for both years in a single row:
SELECT person_uid,
id ,
position_contract_type,
position,
job_suffix,
position_status,
effective_date,
position_employee_class,
timesheet_organization ,
appointment_pct ,
annual_salary ,
per_pay_salary ,
hourly_rate ,
position_title ,
academic_title ,
supervisor_id ,
supervisor_name ,
supervisor_position ,
supervisor_job_suffix ,
supervisor_title ,
assignment_grade ,
position_change_reason ,
position_change_reason_desc
FROM employee_position_cunm posn
WHERE posn.position_contract_type = 'P'
AND posn.position_status <> 'T'
AND posn.effective_date = (SELECT MAX(effective_date)
FROM employee_position_cunm p2
WHERE p2.person_uid = posn.person_uid
AND p2.position = posn.position
AND p2.job_suffix = posn.job_suffix
AND p2.effective_date <= '01-Nov-2014')
order by person_uid
An easy way would be to use OR:
WHERE posn.position_contract_type = 'P' AND
posn.position_status <> 'T' AND
(posn.effective_date = (SELECT MAX(effective_date)
FROM employee_position_cunm p2
WHERE p2.person_uid = posn.person_uid
p2.position = posn.position AND
p2.job_suffix = posn.job_suffix AND
p2.effective_date <= '01-Nov-2014'
) OR
posn.effective_date = (SELECT MAX(effective_date)
FROM employee_position_cunm p2
WHERE p2.person_uid = posn.person_uid
p2.position = posn.position AND
p2.job_suffix = posn.job_suffix AND
p2.effective_date <= '01-Nov-2015'
)
)
In Oracle you could do a UNION or a UNION ALL.
SELECT person_uid,
id ,
position_contract_type,
position,
job_suffix,
position_status,
effective_date,
position_employee_class,
timesheet_organization ,
appointment_pct ,
annual_salary ,
per_pay_salary ,
hourly_rate ,
position_title ,
academic_title ,
supervisor_id ,
supervisor_name ,
supervisor_position ,
supervisor_job_suffix ,
supervisor_title ,
assignment_grade ,
position_change_reason ,
position_change_reason_desc
FROM employee_position_cunm posn
WHERE ...
...
...
UNION ALL
SELECT person_uid,
id ,
position_contract_type,
position,
job_suffix,
position_status,
effective_date,
position_employee_class,
timesheet_organization ,
appointment_pct ,
annual_salary ,
per_pay_salary ,
hourly_rate ,
position_title ,
academic_title ,
supervisor_id ,
supervisor_name ,
supervisor_position ,
supervisor_job_suffix ,
supervisor_title ,
assignment_grade ,
position_change_reason ,
position_change_reason_desc
FROM employee_position_cunm posn
WHERE ....
....
....;

datetime filter mySQL

Im needing to combine 2 queries. The second of two queries is used to filter the rows based on the last updated transfer date (Datetime). I'm using a mySQL database and are attempting to use a filter to bring back the correct results.
Query 1:
SELECT DISTINCT
F.client_license_ID
, EM.create_DTM
, EM.event_ID
, CEQ.consumer_ID
, EM.event_mapping_ID em_ID
, EM.export_value campaign_number
, EM.export_value_2 sequence_number
, EM.export_value_3 campaign_number_2
, EM.export_value_4 sequence_number_2
, EM.export_value_5 ffs_event_id
, EM.export_value_6
, EM.export_value_7
, EM.export_value_8
, EM.export_value_9
, EM.export_value_10
, F.footprint_ID
, F.event_token_ID
FROM data_transfer.Mappings EM
JOIN data_transfer.Event_Queue CEQ ON CEQ.event_ID = EM.event_ID
JOIN efn.Footprints F ON CEQ.consumer_ID = F.consumer_ID
JOIN data_transfer.DT_Runs as DR ON DR.data_transfer_ID = EM.data_transfer_ID
LEFT JOIN efn_data_transfer.CRM_Records LCR ON LCR.consumer_ID = CEQ.consumer_ID
WHERE EM.data_transfer_ID = 24
AND EM.mode = 'production'
AND EM.active_flag = 1
AND F.sample_flag = 0
AND LCR.failureCode = 0
AND EM.create_DTM > ?
Query 2:
SELECT CAST(DATE_SUB(start,INTERVAL 3 DAY) AS CHAR) last_transfer
, CAST(DATE_FORMAT(NOW(),"%Y%m%d") AS CHAR) today
, CAST(DATE_FORMAT(NOW(),"%H%i%s") AS CHAR) "Time"
, CAST(DATE_FORMAT(NOW(),"%m%d%Y") AS CHAR) "Date"
, NOW() timeNow
FROM data_transfer.DT_Runs DTR
WHERE DTR.data_transfer_ID = 24
AND DTR.result = 1
AND DTR.mode = 'production'
ORDER BY DTR.dt_run_ID DESC
LIMIT 1;
My attempt was to add a where filter (AND EM.create_DTM >= DR.start() - INTERVAL 3 DAY) for the last transfer date but it does not work as expected. Currently I have an ETL job that processes both queries feeding the "last transfer" variable from query 2 into the ? variable for the where filter. Help is appreciated
You could implement it as one query.
SELECT DISTINCT
F.client_license_ID
, EM.create_DTM
, EM.event_ID
, CEQ.consumer_ID
, EM.event_mapping_ID em_ID
, EM.export_value campaign_number
, EM.export_value_2 sequence_number
, EM.export_value_3 campaign_number_2
, EM.export_value_4 sequence_number_2
, EM.export_value_5 ffs_event_id
, EM.export_value_6
, EM.export_value_7
, EM.export_value_8
, EM.export_value_9
, EM.export_value_10
, F.footprint_ID
, F.event_token_ID
FROM data_transfer.Mappings EM
JOIN data_transfer.Event_Queue CEQ ON CEQ.event_ID = EM.event_ID
JOIN efn.Footprints F ON CEQ.consumer_ID = F.consumer_ID
JOIN data_transfer.DT_Runs as DR ON DR.data_transfer_ID = EM.data_transfer_ID
LEFT JOIN efn_data_transfer.CRM_Records LCR ON LCR.consumer_ID = CEQ.consumer_ID
WHERE EM.data_transfer_ID = 24
AND EM.mode = 'production'
AND EM.active_flag = 1
AND F.sample_flag = 0
AND LCR.failureCode = 0
AND EM.create_DTM > (SELECT last_transfer FROM (SELECT CAST(DATE_SUB(start,INTERVAL 3 DAY) AS CHAR) last_transfer
, CAST(DATE_FORMAT(NOW(),"%Y%m%d") AS CHAR) today
, CAST(DATE_FORMAT(NOW(),"%H%i%s") AS CHAR) "Time"
, CAST(DATE_FORMAT(NOW(),"%m%d%Y") AS CHAR) "Date"
, NOW() timeNow
FROM data_transfer.DT_Runs DTR
WHERE DTR.data_transfer_ID = 24
AND DTR.result = 1
AND DTR.mode = 'production'
ORDER BY DTR.dt_run_ID DESC
LIMIT 1) )
take a look at datediff:
https://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_datediff
where datediff(EM.create_DTM, DR.start()) >= {x} // where x is the length of 'days' between the to column values.

How to perform multiple calculations with in a single query

I have a situation where in i have to get the data from an Year Ago , Previous Month and Current Month. What is the best way to achieve this ?
I have a table which contains the year,month and data in it. In the below query have added a filter
c.ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo)
This is for an year ago. In the same way if i have to get the previous month and current month, can i do that with in the same query by setting the filters ? how do we do that ?
Is there a better way other than i end up writing 3 select queries and then putting the select to a tmp table and later merging the tables ?
create table #TPTABLE
(
KPIName varchar(150)
,MetricName Varchar(200)
,MetricId INT
,DataSource varchar(50)
,[AnYearAgo] Float
,[PreviousMonth] float
,[CurrentMonth] float
);
insert into #TPTABLE
(KPIName,MetricName,MetricId,DataSource,[AnYearAgo])
SELECT
p.KPIName
,p.MetricName
,p.MetricId
,p.DataSource
,c.Value as [AnYearAgo]
FROM [IntegratedCare].[report].[KPIMetricDetails] p
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c
ON p.[MetricId] = c.MetricId
WHERE c.ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo)
ORDER BY KPI_Id ASC, [MetricId] ASC
SELECT
p.KPIName
,p.MetricName
,p.MetricId
,p.DataSource
,c.Value
,c2.Value
,c3.Value
FROM [IntegratedCare].[report].[KPIMetricDetails] p
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c
ON p.[MetricId] = c.MetricId
AND c.[CommissionerCode] = COALESCE(NULLIF(#Commissioner, ''), c.[CommissionerCode])
ANd ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo)
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c2
ON p.[MetricId] = c2.MetricId
AND c2.[CommissionerCode] = COALESCE(NULLIF(#Commissioner, ''), c2.[CommissionerCode])
ANd c2.ReportMonth = DATENAME(month, #PreviousMonth) and c2.ReportYear = Year(#PreviousMonth)
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c3
ON p.[MetricId] = c3.MetricId
AND c3.[CommissionerCode] = COALESCE(NULLIF(#Commissioner, ''), c3.[CommissionerCode])
ANd c3.ReportMonth = DATENAME(month, #PreviousMonth) and c3.ReportYear = Year(#PreviousMonth)
ORDER BY p.KPI_Id ASC, p.[MetricId] ASC
I think what you need is this:
insert into #TPTABLE
(KPIName,MetricName,MetricId,DataSource,[AnYearAgo])
SELECT
KPIName
,MetricName
,MetricId
,DataSource
,[AnYearAgo]
,[PreviousMonth]
,[CurrentMonth]
FROM (
SELECT
KPIName
,MetricName
,MetricId
,DataSource
,KPI_Id
,sum(case when c.ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo) then c.Value else 0 end) as [AnYearAgo]
,sum(case when c.ReportMonth = DATENAME(month, #PreviousMonth) and c.ReportYear = Year(#PreviousMonth) then c.Value else 0 end) as [PreviousMonth]
,sum(case when c.ReportMonth = DATENAME(month, #CurrentMonth) and c.ReportYear = Year(#CurrentMonth) then c.Value else 0 end) as [CurrentMonth]
FROM [IntegratedCare].[report].[KPIMetricDetails] p
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c
ON p.[MetricId] = c.MetricId
GROUP BY KPIName, MetricName, MetricId, DataSource, KPI_Id
ORDER BY KPI_Id ASC, [MetricId] ASC

how to calculate from each row value in sql

I have a table named general_ledger from which I need to show dr_amount, cr_amount and the balance between them as running_balance. That's why I have written a query that is given below. But I am getting the result of each query like the balance only of current row. But I need to produce the result with the remaining balance. Suppose First row dr_balance is 20000 and cr_balance is 5000 and remaining balance is 15000. In second row only cr_balance is 5000. Now the result should be 10000 with the deduction but my result is -5000. I have no idea how to fix this. Can anyone please help me on this? I need your help very much. Here is my query given below :
SELECT '' AS cost_center_id
, '' AS cost_center_name
, '' AS office_code
, CONVERT('2013-02-01',DATETIME) AS transaction_date
, '' AS accounts_head_id
, '' AS account_name
, '' AS opposite_accounts_head_id
, '' AS opposite_account_name
, 'Opening Balance' AS particulars
, tempOpeningBalance.dr_amount
, tempOpeningBalance.cr_amount
, '' AS voucher_no
, '' AS vin
FROM (SELECT IFNULL(mcoa.account_code,'1101010101100321') AS account_code
, IFNULL(mcoa.account_name,'Cash') AS account_name
, IFNULL(mcoa.account_type,'ASSET') AS accountType
, CAST(IFNULL(SUM(IFNULL(maingl.dr_balance,0)),0) AS DECIMAL(27,5)) AS dr_amount
, CAST(IFNULL(SUM(IFNULL(maingl.cr_balance,0)),0) AS DECIMAL(27,5)) AS cr_amount
FROM master_chart_of_accounts AS mcoa
INNER JOIN chart_of_accounts AS coa ON (mcoa.id = coa.master_chart_of_accounts_id AND mcoa.id = 80)
LEFT JOIN general_ledger AS maingl ON (coa.id = maingl.accounts_head_id AND coa.account_code='1101010101100321')
INNER JOIN
( SELECT gl.accounts_head_id, MAX(gl.gl_id) AS max_gl_id, gl.office_code, gl.office_type, gl.country_id,gl.cost_center_id
FROM general_ledger AS gl
-- INNER JOIN voucher_info AS vi ON (gl.voucher_info_id = vi.id)
-- WHERE vi.posting_date < '2013-02-01' AND
WHERE gl.transaction_date < '2013-02-01' AND
gl.cost_center_id IN ('BI0000000000000000000001') AND
gl.country_id IN (1) AND
gl.office_code IN ('UG500013') AND
1=1
GROUP BY gl.accounts_head_id, gl.office_code, gl.office_type, gl.country_id,gl.cost_center_id
ORDER BY gl.accounts_head_id
) AS tmpgl
ON ( maingl.office_code = tmpgl.office_code
AND maingl.office_type = tmpgl.office_type
AND maingl.accounts_head_id = tmpgl.accounts_head_id
AND maingl.country_id = tmpgl.country_id
AND maingl.cost_center_id = tmpgl.cost_center_id
AND maingl.gl_id = tmpgl.max_gl_id
)
WHERE mcoa.account_status_id = 1 AND
coa.account_status_id = 1
) AS tempOpeningBalance
UNION
SELECT vi.cost_center_id
, cc.center_name AS cost_center_name
, gl.office_code
, vi.posting_date AS transaction_date
, vd.accounts_head_id
, (SELECT chart_of_accounts.account_name FROM chart_of_accounts WHERE chart_of_accounts.id = vd.accounts_head_id) AS account_name
, vd.opposite_accounts_head_id
, (SELECT chart_of_accounts.account_name FROM chart_of_accounts WHERE chart_of_accounts.id = vd.opposite_accounts_head_id) AS opposite_account_name
, vd.particulars
, gl.dr_amount AS dr_amount -- here to check
, gl.cr_amount AS cr_amount
, vi.voucher_no
, vi.vin
FROM general_ledger AS gl
INNER JOIN voucher_info AS vi
ON (gl.voucher_info_id = vi.id)
INNER JOIN cost_center AS cc
ON (vi.cost_center_id = cc.id)
INNER JOIN voucher_details AS vd
ON (vi.id = vd.voucher_info_id)
INNER JOIN chart_of_accounts AS coa
ON (vd.accounts_head_id = coa.id)
WHERE vi.posting_date BETWEEN '2013-02-01' AND'2013-02-28'
AND vi.voucher_status_id = 3
AND vd.status_id = 1
AND vi.office_code = 'UG500063'
AND coa.account_code='1101010101100321'
AND coa.cost_center_id = 'BI0000000000000000000001'
ORDER BY cost_center_name
, office_code
, transaction_date;
Use a variable like this
SET #running_balance=0;
SELECT dr_amount AS dr_amount
, cr_amount AS cr_amount
, #running_balance := (#running_balance + dr_amount - cr_amount)
FROM general_ledger