Doctrine, How can I do a select * (all) statememt? - sql

I'm trying to mimic this sql query:
$sql = "SELECT *, log.id as logid, date_format(shipdate,'%m/%d/%Y') as shipdate
FROM log LEFT JOIN sub ON sub.id = sub_id
LEFT JOIN main ON id = main_id WHERE
shipdate >= '$datestart' AND shipdate <= '$dateend' ";
When I put SELECT * in the createQuery function of Doctrine, an error says it doesn't recognize that statement so I tried to grab all the entities by selecting individual ones:
$query = $this->getEntityManager()
->createQuery('
SELECT
m.dano, m.partno, m.batchno,
s.rackno, s.heatcode, s.diecode,
l.shipdate, l.qtyshipped, l.blno, l.id as logid
FROM
Bundle:Sub s
JOIN
s.main m
JOIN
s.log l
WHERE
l.shipdate >= :fromdate and l.shipdate <= :todate
')->setParameter('fromdate', $fromdate)
->setParameter('todate', $todate);
However when I do it this way, it doesn't return all the data that the original queries does. It skips some rows. Is there another way to be selecting all the entity?

You can mimic the following SQL using DQL. I believe that's the best way to do rather than using create query. Select all in DQL is 'select(alias)'. See my
SELECT *, log.id as logid, date_format(shipdate,'%m/%d/%Y') as shipdate
FROM log LEFT JOIN sub ON sub.id = sub_id
LEFT JOIN main ON id = main_id WHERE
shipdate >= '$datestart' AND shipdate <= '$dateend'
DQL
$dql = $qb2->select('m.dano, m.partno, m.batchno,
s.rackno, s.heatcode, s.diecode,
l.shipdate, l.qtyshipped, l.blno, l.id')
->from('YourBundle:Log','l')
->leftJoin('l.sub', 's', Expr\Join::ON, 's.id = l.sub_id')
->leftJoin('l.main', 'm', Expr\Join::ON, 'm.id = l.main_id')
->where('l.shipdate >= :shipdateStart')
->setParameter('shipdateStart', $datestart)
->where('l.shipdate <= :shipdateEnd')
->setParameter('shipdateEnd', $dateend)
By the way your selecting table and joining tables are slightly different in the given sql example compared to your query in create query function. I mimiced what's in your raw SQL which is listed above. Hope this helps you to understand converting SQL in to DQL.
Regards,

Related

SQL Server Loop Over Records

I have a view vwDocumentLinks with data as shown below:
I have another table RiskTypes with data as below.
The link between the table & viewis : Idx25 = Risk Type and LinkDocNo = DocumentType. What I am trying to achieve is to get DocumentType in RiskTypes that's not in the view vwDocumentLinks foreach BaseValue and where Idx25 = RiskType. An example using a single BaseValue will be:
SELECT * FROM RiskTypeDocuments WHERE RiskType = 'BUSINESS LIMITED COMPANY' AND DocumentType NOT IN (SELECT LINKDOCNO FROM DBO.VWLINKS WHERE BaseValue = '00007573-1637-4B8E-9374-730AF58BCFB6')
I tried the below query and it's not working as expected. Any help will be greatly appreciated. I am a newbie in SQL
SELECT dbo.RiskTypeDocuments.DocumentType,
dbo.RiskTypeDocuments.RiskType,
dbo.vwLinks.BaseValue AS Document
FROM dbo.vwLinks LEFT OUTER JOIN
dbo.RiskTypeDocuments ON dbo.vwLinks.LinkDocNo =
dbo.RiskTypeDocuments.DocumentType AND dbo.vwLinks.Idx25 =
dbo.RiskTypeDocuments.RiskType
WHERE dbo.RiskTypeDocuments.DocumentType IS NOT NULL
ORDER BY Document
NB: I can't change the schema. I can only create views from the existing tables.
Sample Data from the two datasets: vwDocumentLinks & RiskTypeDocuments
SELECT a.DocumentType,
a.RiskType,
b.BaseValue AS Document
FROM dbo.RiskTypeDocuments as a
INNER JOIN (Select distinct Idx25, BaseValue from vwDocumentLinks) as b on b.Idx25 = a.RiskType
where a.DocumentType not in (Select LINKDOCNO from vwDocumentLinks as c where c.basevalue = b.BaseValue )
I think what you are looking for is NOT EXISTS. It takes a little to get your head around, but the idea is to have what is called a correlated subquery. The subquery is joined to the main query, hence the term correlated.
SELECT *
FROM RiskTypeDocuments
WHERE NOT EXISTS (
SELECT 1 FROM vwDocumentLinks
WHERE RiskTypeDocuments.RiskType = vwDocumentLinks.idx25
AND RiskTypeDocuments.DocumentType = vwDocumentLinks.LinkDocNo
)
If you want to retrieve the records which don't exist in the view then
Try like this
SELECT d.DocumentType,
d.RiskType,
v.BaseValue
FROM dbo.vwLinks AS v
OUTER JOIN dbo.RiskTypeDocuments d ON v.LinkDocNo = d.DocumentType AND v.vwLinks.Idx25 =d.RiskType
WHERE v.BaseValue IS NULL
ORDER BY DocumentType

Confused in join query in SQL

The following works:
SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY, BM.BOQ_ITEM_NO,
IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
AND BCI.STATUS = 'Y'
AND BM.STATUS = 'Y'
order by boq_item_no;
Results:
But after joining many tables with that query, the result is confusing:
SELECT (SELECT CMN_NAME
FROM CMN_MST
WHERE CMN_CODE= BRI.CMN_RLTY_MTRL) MTRL,
RRI.RRI_RLTY_RATE AS RATE,
I.BOQ_ITEM_NO,
(TRIM(TO_CHAR(IBAD.IPABD_CUR_QTY,
'9999999999999999999999999999990.999'))) AS IPABD_CUR_QTY,
TRIM(TO_CHAR(BRI.BRI_WT_FACTOR,
'9999999999999999999999999999990.999')) AS WT,
TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR),
'9999999999999999999999990.999')) AS RLTY_QTY,
(TRIM(TO_CHAR((IBAD.IPABD_CUR_QTY*BRI.BRI_WT_FACTOR*RRI.RRI_RLTY_RATE),
'9999999999999999999999990.99'))) AS TOT_AMT,
I.TRM_CODE AS TRM
FROM
(SELECT * FROM ipa_boq_abstrct_dtl) IBAD
INNER JOIN
(SELECT * FROM BOQ_RLTY_INF) BRI
ON IBAD.BCI_CODE = BRI.BCI_CODE
INNER JOIN
(SELECT * FROM RLTY_RATE_INF) RRI
ON BRI.CMN_RLTY_MTRL = RRI.CMN_RLTY_MTRL
INNER JOIN
( SELECT IBAD.TRM_CODE, IBAD.IPABD_CUR_QTY,
BM.BOQ_ITEM_NO, IBAD.BCI_CODE, BCI.BOQ_CODE
FROM IPA_BOQ_ABSTRCT_DTL IBAD,
BOQ_CONFIG_INF BCI,BOQ_MST BM
WHERE
BM.BOQ_CODE = BCI.BOQ_CODE
AND BCI.BCI_CODE = IBAD.BCI_CODE
and BCI.status = 'Y'
and bm.status = 'Y') I
ON BRI.BCI_CODE = I.BCI_CODE
AND I.TRM_CODE = BRI.TRM_CODE
AND BRI.TRM_CODE =4
group by BRI.CMN_RLTY_MTRL, RRI.RRI_RLTY_RATE, I.BOQ_ITEM_NO,
IBAD.IPABD_CUR_QTY, BRI.BRI_WT_FACTOR, I.TRM_CODE, I.bci_code
order by BRI.CMN_RLTY_MTRL
Results:
TRM should be 11 instead of 4 in the first row.
you getting 4 because you use
AND BRI.TRM_CODE =4
if you remove this criter you can get true result
In your first query, both of the rows you've highlighted have BCI_CODE=1866.
In the second query, you are joining that result set with a number of others (which come from the same tables, which seems odd). In particular, you are joining from the subquery to another table using BCI_CODE, and from there to (SELECT * FROM ipa_boq_abstrct_dtl) IBAD. Since both of the rows from the subquery have the same BCI_CODE, they will join to the same rows in the other tables.
The quantity that you are actually displaying in the second query is from (SELECT * FROM ipa_boq_abstrct_dtl) IBAD, not from the other subquery.
Is the problem simply that you mean to select I.IPABD_CUR_QTY instead of IBAD.IPABD_CUR_QTY?
You might find this clearer if you did not reuse the same aliases for tables at multiple points in the query.

Column is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause

Ok here's my View (vw_LiftEquip)
SELECT dbo.tbl_equip_swl_unit.unit_id,
dbo.tbl_equip_swl_unit.unit_name,
dbo.tbl_equip_swl_unit.archived,
dbo.tbl_categories.category_id,
dbo.tbl_categories.categoryName,
dbo.tbl_categories.parentCategory,
dbo.tbl_categories.sub_category,
dbo.tbl_categories.desc_category,
dbo.tbl_categories.description,
dbo.tbl_categories.miscellaneous,
dbo.tbl_categories.category_archived,
dbo.tbl_equip_swl_unit.unit_name AS Expr1,
dbo.tbl_categories.categoryName AS Expr2,
dbo.tbl_categories.description AS Expr3,
dbo.tbl_equip_depts.dept_name,
dbo.tbl_equip_man.man_name,
dbo.tbl_Lifting_Gear.e_defects AS Expr7,
dbo.tbl_Lifting_Gear.e_defects_desc AS Expr8,
dbo.tbl_Lifting_Gear.e_defects_date AS Expr9,
dbo.tbl_equipment.equipment_id,
dbo.tbl_equipment.e_contract_no,
dbo.tbl_equipment.slID,
dbo.tbl_equipment.e_entered_by,
dbo.tbl_equipment.e_serial,
dbo.tbl_equipment.e_model,
dbo.tbl_equipment.e_description,
dbo.tbl_equipment.e_location_id,
dbo.tbl_equipment.e_owner_id,
dbo.tbl_equipment.e_department_id,
dbo.tbl_equipment.e_manafacture_id,
dbo.tbl_equipment.e_manDate1,
dbo.tbl_equipment.e_manDate2,
dbo.tbl_equipment.e_manDate3,
dbo.tbl_equipment.e_dimensions,
dbo.tbl_equipment.e_test_no,
dbo.tbl_equipment.e_firstDate1,
dbo.tbl_equipment.e_firstDate2,
dbo.tbl_equipment.e_firstDate3,
dbo.tbl_equipment.e_prevDate1,
dbo.tbl_equipment.e_prevDate2,
dbo.tbl_equipment.e_prevDate3,
dbo.tbl_equipment.e_insp_frequency,
dbo.tbl_equipment.e_swl,
dbo.tbl_equipment.e_swl_unit_id,
dbo.tbl_equipment.e_swl_notes,
dbo.tbl_equipment.e_cat_id,
dbo.tbl_equipment.e_sub_id,
dbo.tbl_equipment.e_parent_id,
dbo.tbl_equipment.e_last_inspector,
dbo.tbl_equipment.e_last_company,
dbo.tbl_equipment.e_deleted AS Expr11,
dbo.tbl_equipment.e_deleted_desc AS Expr12,
dbo.tbl_equipment.e_deleted_date AS Expr13,
dbo.tbl_equipment.e_deleted_insp AS Expr14,
dbo.tbl_Lifting_Gear.e_defects_action AS Expr15,
dbo.tbl_equipment.e_rig_location,
dbo.tbl_Lifting_Gear.e_add_type AS Expr17,
dbo.tbl_Lifting_Gear.con_id,
dbo.tbl_Lifting_Gear.lifting_date,
dbo.tbl_Lifting_Gear.lifting_ref_no,
dbo.tbl_Lifting_Gear.e_id,
dbo.tbl_Lifting_Gear.inspector_id,
dbo.tbl_Lifting_Gear.lift_testCert,
dbo.tbl_Lifting_Gear.lift_rig_location,
dbo.tbl_Lifting_Gear.inspected,
dbo.tbl_Lifting_Gear.lifting_through,
dbo.tbl_Lifting_Gear.liftingNDT,
dbo.tbl_Lifting_Gear.liftingTest,
dbo.tbl_Lifting_Gear.e_defects,
dbo.tbl_Lifting_Gear.e_defects_desc,
dbo.tbl_Lifting_Gear.e_defects_date,
dbo.tbl_Lifting_Gear.e_defects_action,
dbo.tbl_Lifting_Gear.lift_department_id,
dbo.tbl_Lifting_Gear.lifting_loc
FROM dbo.tbl_equipment
INNER JOIN dbo.tbl_equip_swl_unit
ON dbo.tbl_equipment.e_swl_unit_id = dbo.tbl_equip_swl_unit.unit_id
INNER JOIN dbo.tbl_categories
ON dbo.tbl_equipment.e_cat_id = dbo.tbl_categories.category_id
INNER JOIN dbo.tbl_equip_depts
ON dbo.tbl_equipment.e_department_id = dbo.tbl_equip_depts.dept_id
INNER JOIN dbo.tbl_equip_man
ON dbo.tbl_equipment.e_manafacture_id = dbo.tbl_equip_man.man_id
INNER JOIN dbo.vwSubCategory
ON dbo.tbl_equipment.e_sub_id = dbo.vwSubCategory.category_id
INNER JOIN dbo.vwDescCategory
ON dbo.tbl_equipment.e_cat_id = dbo.vwDescCategory.category_id
INNER JOIN dbo.tbl_Lifting_Gear
ON dbo.tbl_equipment.equipment_id = dbo.tbl_Lifting_Gear.e_id
And here's the select statement with subquery that I am using:
SELECT *
FROM vw_LiftEquip
WHERE lifting_loc = ? AND
con_id = ? AND
EXPR11 =
'N'(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
)
ORDER BY lifting_ref_no,
category_id,
e_swl,
e_serial
I get the error :
Column "vw_LiftEquip.category_id" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
Can't see why its returning that error, this is admittedly the first time I've ran a subquery on such a complex view, and I am a bit lost, thanks in advance for any help. I have looked through the similar posts and can find no answers to this one, sorry if I am just being dumb.
You are missing AND between EXPR11 = 'N' and (SELECT MAX(...
Otherwise, it looks OK. MAX without GROUP BY is allowed if you have no other columns in the SELECT
Update: #hvd also noted that you have nothing to compare to MAX(lifting_date). See comment
Update 2,
SELECT *
FROM vw_LiftEquip v1
CROSS JOIN
(
SELECT MAX(lifting_date) AS maxLift
FROM vw_LiftEquip
WHERE e_id = equipment_id
) v2
WHERE v1.lifting_loc = ? AND
v1.con_id = ? AND
v1.EXPR11 = 'N'
ORDER BY v1.lifting_ref_no,
v1.category_id,
v1.e_swl,
v1.e_serial

SQL Selecting based off largest date from different table

I am attempting to write a query that pulls Order information from various tables. I have hit a road block at the target date value.
It seems that every time a target date is changed a new row is added in that table. All I want is to be able to select only the newest Target Date. What should I do?
select Distinct
OR01001 AS OrderNumber,
OR01002 AS OrderType,
OR01003 AS CustomerCode,
OR01015 AS OrderDate,
OR01017 AS CustomerREP,
OR01018 AS ContactPerson,
OR01019 AS SalesmanNumber,
OR03011 - OR03012 AS OpenQuantity,
SC03003 AS StockBalance,
OR01050 AS WarehouseNumber,
OR01072 AS CustomerPO,
OR03005 AS ItemCode,
OR03002 AS LineNumber,
OR500100.OR50004 As TargetDate
from OR010100
INNER Join OR030100 ON OR030100.OR03001 = OR010100.OR01001
INNER Join SL010100 ON SL010100.SL01001 = OR010100.OR01003
INNER Join SC030100 ON SC030100.SC03001 = OR030100.OR03005
Inner JOIN OR500100 ON OR500100.OR50001 = OR010100.OR01001
where OR010100.OR01002 <> 0 AND OR010100.OR01002 <> 6 AND OR01017 = 'SLOTT'
Order by OR01017 ASC;
If I understand your columns correctly, here's one way:
SELECT ...,
OR500100A.OR50004 AS TargetDate
FROM ...
INNER JOIN OR500100 AS OR500100A ON OR500100A.OR50001 = OR010100.OR01001
AND NOT EXISTS(SELECT 1 FROM OR500100 AS OR500100B
WHERE OR500100B.OR5001 = OR010100.OR01001
AND OR500100B.OR50004 > OR500100A.OR50004)
...
This makes sure you only get one OR500100 row with the latest value in OR50004 for the given OR5001.
from what i understand,
SELECT
...
MAX(OR500100.OR50004) As TargetDate
FROM...
WHERE...
GROUP BY --everything but OR500100.OR50004
ORDER BY...
should do the trick
EDIT: ty Ic.

SQL - Derived tables issue

I have the following SQL query:
SELECT VehicleRegistrations.ID, VehicleRegistrations.VehicleReg,
VehicleRegistrations.Phone, VehicleType.VehicleTypeDescription,
dt.ID AS 'CostID', dt.IVehHire, dt.FixedCostPerYear, dt.VehicleParts,
dt.MaintenancePerMile, dt.DateEffective
FROM VehicleRegistrations
INNER JOIN VehicleType ON VehicleRegistrations.VehicleType = VehicleType.ID
LEFT OUTER JOIN (SELECT TOP (1) ID, VehicleRegID, DateEffective, IVehHire,
FixedCostPerYear, VehicleParts, MaintenancePerMile
FROM VehicleFixedCosts
WHERE (DateEffective <= GETDATE())
ORDER BY DateEffective DESC) AS dt
ON dt.VehicleRegID = VehicleRegistrations.ID
What I basically want to do is always select the top 1 record from the 'VehicleFixedCosts' table, where the VehicleRegID matches the one in the main query. What is happening here is that it's selecting the top row before the join, so if the vehicle registration of the top row doesn't match the one we're joining to it returns nothing.
Any ideas? I really don't want to have use subselects for each of the columns I need to return
Try this:
SELECT vr.ID, vr.VehicleReg,
vr.Phone, VehicleType.VehicleTypeDescription,
dt.ID AS 'CostID', dt.IVehHire, dt.FixedCostPerYear, dt.VehicleParts,
dt.MaintenancePerMile, dt.DateEffective
FROM VehicleRegistrations vr
INNER JOIN VehicleType ON vr.VehicleType = VehicleType.ID
LEFT OUTER JOIN (
SELECT ID, VehicleRegID, DateEffective, IVehHire, FixedCostPerYear, VehicleParts, MaintenancePerMile
FROM VehicleFixedCosts vfc
JOIN (
select VehicleRegID, max(DateEffective) as DateEffective
from VehicleFixedCosts
where DateEffective <= getdate()
group by VehicleRegID
) t ON vfc.VehicleRegID = t.VehicleRegID and vfc.DateEffective = t.DateEffective
) AS dt
ON dt.VehicleRegID = vr.ID
Subquery underneath dt might need some grouping but without schema (and maybe sample data) it's hard to say which column should be involved in that.