In my GridView, the number of rows returned is not the same showed in the upper right corner. In the corner, the grid counts 7450 rows but in reality it returns 4351 rows. Here is an example of wrong behavior: Screenshot In the example the Gridview renders 1 row (it is correct) but the summary in the corner says "Showing 1-1 of 4 items). I have probably found what is causing the error by reading this post: Yii2 gridview showing more records than the table. This error also causes the pagination to be broken. Unfortunately that solution didn't solve my problem. Or maybe I'm missing something.
My case
I need to display relational data in a Gridview so I have created this relation in my AuthorsProjectPpi Model:
public function getInstitutionName(){
return $this->hasOne(AuthorsInstitution::className(), ['md_institution_tokens'=>'ppi_organization']);
}
The problem arises in the search function of the AuthorsProjectPpiSearch Model:
public function search($params)
{
$query = AuthorsProjectPpi::find();
$query->joinWith('institutionName');
...
}
That Join produces 7450 rows (and so the count of the rows in the upper right corner of the Gridview is 7450) but than the Gridview instantiates just 4351 rows (that is the number that I want).
If I comment the Join:
public function search($params)
{
$query = AuthorsProjectPpi::find();
//$query->joinWith('institutionName');
...
}
In the upper right corner is shown the correct number (4351), the column of the relation is also displayed correctly but I can't filter the results by that column.
I can't really fix this problem. I'm using Kartik's Gridview if this can help.
Solved
I just forgot to put a GroupBy to the query...
public function search($params)
{
$query = AuthorsProjectPpi::find();
$query->joinWith('institutionName')->groupBy('id');
...
}
That completely solved the problem.
Related
I have models named Issue and Label. Each issue can have many labels. Each label can have many issues.
I am trying to build a query that will return an issue that contains all of the supplied labels.
For instance, if I supply ['bug', 'fix', 'enhancement'] I want issues that have all three of those three labels at least.
Currently, I have:
labels = ['bug', 'fix', 'enhancement']
Issue.joins(:labels).where(labels: { name: labels }).distinct
But this is insufficient as it returns issues that have at least one of the label names. I see this is because is because an 'IN' operator is generated:
WHERE "labels"."name" IN ('bug', 'fix', 'enhancement')
And from here on, I'm lost. The labels array can be any length. Can I get the result I want in a single query?
How can I find rows in a table that point to rows in another that match all the specified column values?
I didn't check it, but maybe this approach could work
Issue.select('issues.id, count(labels.id) as cnt').includes(:labels).where(labels: { name: labels }).group('issues.id').having("cnt = #{labels.size}");
I have a column pointsAwarded decimal(9,3) and I have the following LInq
db.TableName.Select(x=>x.pointsAwarded >0)
The fact is that it is not filtering the data and returning me the whole result set.
How to compare it?
I tried with x.pointsAwarded.value>0 and x.pointsAwarded.value>0.000 and
x.pointsAwarded > (Decimal?)0
but with no luck.
Pls help
Try using a Where instead of a Select
db.TableName.Where(x=>x.pointsAwarded > 0)
UPDATE:
This answer has been given more credit than it previously deserved, so I will elaburete a little
The Where statement acts as the filter. It determins whitch elements the returned list should contain.
The Select statement is the projection of the elements. Given a list of elements, how would you like them presented.
So far I have a query with a result set (in a temp table) with several columns but I am only concerned with four. One is a customer ID(varchar), one is Date (smalldatetime), one is Amount(money) and the last is Type(char). I have multiple rows with the same custmer ID and want to evaluate them based on Date, Amount and Type. For example:
Customer ID Date Amount Type
A 1-1-10 200 blue
A 1-1-10 400 green
A 1-2-10 400 green
B 1-11-10 100 blue
B 1-11-10 100 red
For all occurrences of A I want to compare them to identify only one, first by earliest date, then by greatest Amount, then if still tied by comparing Types. I would then return one row for each customer.
I would provide some of the query but I am at home now after spending two days trying to get a correct result. It looks something like this:
(query to populate #tempTable)
GROUP BY customer_id
HAVING date_cd =
(SELECT MIN(date_cd)
FROM order_table ot
WHERE ot.customerID = #tempTable.customerID
)
OR date_cd IS NULL
I assume the HAVING would result in only one row per customer_id. This did not end up being the case since there were some ties there.
I am not sure I can do the OR - there are some with NULL values here - and it did not account for the step to the next comparison if they were all the same anyway. I am not seeing a way to avoid doing some row processing of the temp table with some kind of IF or WHERE loop.
As I write I am thinking maybe I use #tempTable.date_cd in the HAVING clause instead of looking at the original table. but that should return the same dates?
Am I on the right track or is there something missing? Suggestions? More info??
try below query :-
select * from #tempTable
GROUP BY customer_id
HAVING isnull(date_cd,"1900/01/01") =min(isnull(date_cd,"1900/01/01"))
I'm using vaadin for UI,I have a entity class which has #OneToMany relationship, so Entity class has a list. so I want to display those values in a vaadin table,Could anyone explain me how to do that? Thank you, here is my class details
#OneToMany
private List<Driver> driverList = new ArrayList<Driver>()
This field in TempLocation class.
so when I query from the data I get one city and list of drivers. In vaadin table I could display query result in a single row(assume I have only one record in a database with more than one Driver)
Lets say my table has two columns "Location" and "Driver", so I want to display the results in multiple rows,I want to go through the List and take one drive at time display along with the City
Currently how it display in the table.
|Driver_______________| Location | (Table head)
[Driver1,Driver2,Driver3] | Kolonnanwa (row)
I want display this
|Driver______________| Location | (Table head)
Driver1______________|Kolonnawa (row 1)
Driver2______________| Kolonnawa (row 2)
Driver3______________| Kolonnanwa (row 3)
"_" used to display spaces ,
Hope you got what I want to express and can anyone tell me how to do this?
Thankxx in Advance
Thank you,
Cheers
If you only want a different way of filling the table , I recommend just iterating over the List of your drivers and create one row for everyone (assuming every driver knows his city)
Check this example:
/* Create the table with a caption. */
Table table = new Table("This is my Table");
/* Define the names and data types of columns.
* The "default value" parameter is meaningless here. */
table.addContainerProperty("Driver", String.class, null);
table.addContainerProperty("City", String.class, null);
/* Add a few items in the table. */
int i = 1;
for(Driver driver : driverslist){
table.addItem(new Object[] {
driver.getName(),driver.getCity(), new Integer(i));
i++
}
The Integer in the addItem()-method is for the rownumber.
Please check the articles given in the vaadin book about the use of the table component.
I'm trying to make tables inside tables in WORD. of course in finall program it will be dinamical, which is not in this sample.
Here is my sample code.
var
aTable, bTable, cTable : OLEVariant;
begin
m_WordApplication := CreateOleObject('Word.Application') ;
m_WordDocument := m_WordApplication.Documents.Add;
aTable := m_WordDocument.Tables.Add(m_WordApplication.Selection.Range, 2, 1);
aTable.Borders.Item(wdBorderLeft).LineStyle:=wdLineStyleSingle;
aTable.Borders.Item(wdBorderRight).LineStyle:=wdLineStyleSingle;
aTable.Borders.Item(wdBorderTop).LineStyle:=wdLineStyleSingle;
aTable.Borders.Item(wdBorderBottom).LineStyle:=wdLineStyleSingle;
bTable := m_WordDocument.Tables.Add(aTable.Cell(1, 1).Range, 2, 1);
bTable.Borders.Item(wdBorderLeft).LineStyle:=wdLineStyleSingle;
bTable.Borders.Item(wdBorderRight).LineStyle:=wdLineStyleSingle;
bTable.Borders.Item(wdBorderTop).LineStyle:=wdLineStyleSingle;
bTable.Borders.Item(wdBorderBottom).LineStyle:=wdLineStyleSingle;
cTable := m_WordDocument.Tables.Add(aTable.Cell(2, 1).Range, 3, 1);
cTable.Borders.Item(wdBorderLeft).LineStyle:=wdLineStyleSingle;
cTable.Borders.Item(wdBorderRight).LineStyle:=wdLineStyleSingle;
cTable.Borders.Item(wdBorderTop).LineStyle:=wdLineStyleSingle;
cTable.Borders.Item(wdBorderBottom).LineStyle:=wdLineStyleSingle;
m_WordDocument.SaveAs('C:/test.doc', False) ;
m_WordApplication.Quit(False);
Firstly i put new table(2 rows, 1 column) on position of the cursor, and then i try to put second table in cell(1,1) and third in cell(2,1) of the first table. second table has also 2 rows and 1 column, but third table has 3 rows and 1 column. but instead of what i want i get second and third table whit only one row, regardless if i putt something in thier cell or not.i always see only the last string i put in that table.
even more, if i put 1 row and 2 column table inside first table, than everything is normal.
can you help me.
thanks, Rok
When you have problems creating those tables in code, do the following:
Open Word
record a new macro
While recording, build the table you want, then stop the recording.
View your macro code in the Visual Basic Editor and try to translate that to OLE-automation code (which isn't that hard, it's almost the same)
aTable.Borders.Item(wdBorderVertical).LineStyle:=wdLineStyleSingle;
aTable.Borders.Item(wdBorderHorizontal).LineStyle:=wdLineStyleSingle;
You will have to do the same for bTable & cTable.
When you add more than 1 row/column, it will need border to separate it (i.e to separate 1 row from another OR separate 1 column from another).
Hope this helps.