Extbase-DISTINCT Values from repository - extbase

Fetch unique room numbers from my database.
My table is tx_example_domain_model_room which has columns startdatetime, enddatetime and roomKey. I want to fetch roomKey greater than given datetime. When I query, the results returns all the roomKey that are greater than given datetime, all the roomKey having more than the given datetime comes up. However, its not distinct. I want to get the distinct rooms. Below is my code:
List.html List
f:form.select options="{roomKeys}" optionLabelField="roomKey"
Could you let me know how to get distinct values. One more detail: Room is a model that contains the attributes roomKey, startdatetime and enddatatime.
Controller
$roomKey = $this->roomRepository->RoomKeyFetcher($enddatetime, $startdatetime);
var_dump($roomKey);
$unique_rooms = array_unique($roomKey);
$this->view->assign('roomKeys', $unique_rooms);
Repository:
public function RoomKey($enddatetime, $startdatetime) {
$query = $this->createQuery();
$query->statement('SELECT * FROM tx_example_domain_model_room
WHERE startdatetime >= ? OR enddatetime <= ?',
[$enddatetime, $startdatetime]);
$results = $query->execute();
return $results;
}

Just using DISTINCT keyword on roomkey should do it.
$query->statement('SELECT DISTINCT roomKey FROM tx_example_domain_model_room
WHERE startdatetime >= ? OR enddatetime <= ?',
[$enddatetime, $startdatetime]);

Related

using doctrine and querybuilder, between two date

I want to retrieve some data using queryBuilder, the condition is to use a datetime field on parent table and pass it to where condition, the child table have two date start and end, the whole condition is to select parent row depend on date between the two date in child table
the code is:
$qb->select('parent,child')
->from($this->class, 'parent')
->innerJoin('parent.childTable', 'child')
//other join
// and where
//CONDITION -> startdate <= $date AND enddate >= $date
$betweenDates = $qb->expr()->andX(
$qb->expr()->gt("child.dateStart", "parent.datetime"),
$qb->expr()->lt("child.dateEnd", "parent.datetime")
);
//CONDITION 4 -> enddate == NULL
$endDateNull = $qb->expr()->isNull( 'child.dateEnd');
$dates = $qb->expr()->orX($betweenDates, $endDateNull);
// take care of dateEnd if it's null
$qb->expr()->andX($dates);
the problem is the where condition not work and the select still give me childs not respect date condition
any help would be greatly appreciated.

SQL retrieving data NOT IN

SELECT ID, Name
FROM dbo.AmenitiesList
WHERE TypeID=#Type and Status = 'Available'
AND ID NOT IN
(SELECT AmenitiesID FROM dbo.ReservationList
WHERE Status = 'Cancelled' AND StartDate between #Arrival and #Departure
or EndDate between #Arrival and #Departure
or #Arrival between StartDate and EndDate
or #Departure between StartDate and EndDate)
This is my query, I want to display all the Available Amenities that the status is 'Cancelled' and the Arrival Date and Departure date is not between in the ArrivalDate and Departure date in Database. But when retrieving data, I didn't get the Amenities available because when the Status is cancelled it triggers the other condition about those in between dates. How to Avoid that?
I want to display Amenities that is Cancelled and also not between ArrivalDate and Departure Date
Thank you in advance guys!
For performance and optimization, consider table variables.
DECLARE #TABLE AS TABLE
(
AmenityID INT PRIMARY KEY CLUSTERED
)
INSERT INTO #TABLE
SELECT AmenitiesID FROM dbo.ReservationList
--Your conditions
--Get values that exist
SELECT * FROM AmentitiesList al
INNER JOIN #Table t on al.AmenityID = t.AmenityID
--Get values that don't
SELECT * FROM AmentitiesList al
LEFT JOIN #Table t on al.AmenityID = t.AmenityID
WHERE t.AmenityID IS NULL
Just because code is shorter, doesn't mean it scales. Left Joins are also a pain...
You could easily get rid of that too by using a table variable.
DECLARE #AmenityList AS TABLE
(
AmenityID INT PRIMARY KEY CLUSTERED
Matched BIT DEFAULT(0)
)
INSERT INTO #AmenityList
Select AmenityID FROM AmentitiesList
UPDATE #AmenityList SET Matched = 1
FROM #AmenitityList al
INNER JOIN #Table t on t.AmentityID = al.AmentityID
SELECT * FROM #AmentityList WHERE Matched = 0
How about this version?
SELECT ID, Name
FROM dbo.AmenitiesList
WHERE TypeID=#Type and Status = 'Available'
AND ID NOT IN
(SELECT AmenitiesID FROM dbo.ReservationList
WHERE Status = 'Cancelled' AND (StartDate between #Arrival and #Departure
or EndDate between #Arrival and #Departure
or #Arrival between StartDate and EndDate
or #Departure between StartDate and EndDate))
SELECT ID, Name
FROM dbo.AmenitiesList
WHERE TypeID=#Type and Status = 'Available'
AND ID NOT IN
(SELECT AmenitiesID FROM dbo.ReservationList
WHERE Status != 'Cancelled' AND Status != 'Check Out' AND ((#Arrival <= EndDate) AND (#Departure >= StartDate)))
This solve my problem! By the way thank you guys for spending time giving information to me! God Bless!

Doctrine2 select distinct with orderby (case when)

I am having some trouble with doctrine2. I want to order a query but by day of the week.
What do I mean:
If where the day of the date given is Tuesday, I want to have it ordered by Tuesday, Wednseday, ..., Sunday, Monday.
But an performance can have multiple days.
The code I got here does the trick for the order by
public function getValidPerformancesByDay2($date, $max = 25, $from, $asSql = false){
$myday = intVal(date('w',strtotime($date)));
$q = $this->getEntityManager()
->createQueryBuilder()
->select('DISTINCT textdesc,
CASE WHEN (perfdays.id < '. $myday .') THEN perfdays.id + 8
ELSE perfdays.id END AS HIDDEN sortvalue')
->from ('sys4winsegundaBundle:Performance','textdesc')
->join('textdesc.days', 'perfdays')
->where ('textdesc.enddate >= :date')
->andWhere('textdesc.isvalid = true')
->orderBy('sortvalue','ASC')
->setMaxResults($max)
->setFirstResult($from)
->setParameter('date',$date)
;
$query = $q->getQuery();
if ($asSql){
return $query;
}
return $query->getResult();
}
But unfortunately, when I look at the query that has been sent it is:
SELECT DISTINCT p0_.id AS id0, p0_.name AS name1, p0_.duration AS duration2,
p0_.addedby AS addedby3, p0_.startdate AS startdate4, p0_.enddate AS enddate5,
p0_.starthour AS starthour6, p0_.flyer AS flyer7, p0_.price AS price8,
p0_.discount AS discount9, p0_.isvalid AS isvalid10,
p0_.archivedon AS archivedon11, p0_.description AS description12,
p0_.weblink AS weblink13, p0_.techinfo AS techinfo14, p0_.slug AS slug15,
CASE WHEN (d1_.id < 4) THEN d1_.id + 8 ELSE d1_.id END AS sclr16,
p0_.place_id AS place_id17, p0_.gallery_id AS gallery_id18 FROM performances
p0_ INNER JOIN performance_day p2_ ON p0_.id = p2_.performance_id
INNER JOIN days d1_ ON d1_.id = p2_.day_id WHERE p0_.enddate >= ? AND
p0_.isvalid = 1 ORDER BY sclr16 ASC OFFSET 0
Parameters: ['2012-08-23']
Time: 5.13 ms
Which means that if a performance occurred 3 times a week, I get 3 occurrences.
anyone got an idea?
EDIT
my english being pretty bad, i lltry to explain it differently:
Well i got art performances that occurs on various days.
What i want to do is order them by nearest occurence in time.
But the way i sent it to database is with a startdate, an enddate and then what days it occurs (Tuesday, wednesday...)
My query does this( ordering by nearest one) but as some performance occured for example on wednesdays y fridays, my query will return that performance 2 times (on for wednsday and the other one for friday) while i should only retrieve on occurance of each performance but with the same order (nearest first)
If you want 1 occurrence per week use
$q->groupBy()
For the date converted to week number. And use count() in your select. I'm not sure that I Understand your question.

SQL Select fields with a value of 'Y' and order by date descending, then select all others and order by another field ascending

I am generating an SQL query:
SELECT * FROM ToDoList
WHERE ws_status <> 'Completed'
AND (user_id= 'TESTUSR' OR ww_cover='TESTUSR'
OR (ws_status = 'Orphan' AND wwt_workgroupid IN (108)))
**ORDER BY psc_alt_code ASC**
And I need to list all results with wi_urgent set to 'Y' and order them by date Desc *first and then list all other results ordered by psc_alt_code descending* so I thought something like this would suffice:
ORDER BY (wi_urgent = 'Y') DESC, psc_alt_code ASC
I am getting SqlClient.SqlException: Incorrect syntax near '=' error when trying to run that query. Please note that I am querying an SQL View if that makes a difference?
You can use a case expression in the order by
SELECT * FROM ToDoList
WHERE ws_status <> 'Completed'
AND (user_id= 'TESTUSR' OR ww_cover='TESTUSR'
OR (ws_status = 'Orphan' AND wwt_workgroupid IN (108)))
ORDER BY CASE WHEN wi_urgent = 'Y' THEN 0 ELSE 1 END ASC
,psc_alt_code
I don't think you can do wi_urgent = 'Y' in an ORDER BY.
Since you're looking for all results with wi_urgent, try adding it to the WHERE clause:
SELECT * FROM ToDoList
WHERE ws_status <> 'Completed'
AND (user_id= 'TESTUSR' OR ww_cover='TESTUSR'
OR (ws_status = 'Orphan' AND wwt_workgroupid IN (108)))
AND wi_urgent = 'Y'
ORDER BY wi_urgent DESC,
psc_alt_code ASC

Syntax for collecting data in var query

I am collecting some data from database using var query and storing it in an integer. Below is the code:
var query1 = from meet_emp in db.Meet_Emps
where meet_emp.Employee_ID == empid
select meet_emp.Meeting_ID;
int meetNum = query1.First();
Here query1 contains multiple meeting ids. I wish to store all id's into an int variable or int array as I would be using each meeting id later into another query. With syntax "int meetNum = query1.First()", I get only the first meeting id.
How do I get all the meeting id's
You can leave the data just as it is in variable query1, then join it later with your final query that uses that list:
from blah in db.Stuff
join query1 on query1.Meeting_ID equals blah.Meeting_ID
select ...;
Just change to ToList then you will have a list of IDs
var query1 = from meet_emp in db.Meet_Emps
where meet_emp.Employee_ID == empid
select meet_emp.Meeting_ID;
var meetNum = query1.ToList();

Resources