Rails where two tables have the same data? - ruby-on-rails

I'm trying to create a table in my view and populate it on some conditions.
I have two tables, Both have two columns inside, One columns called event_url and the other is gmiurl. The table with gmiurl inside is called GMITable and the other is called newevent
Basically i want to show everything inside the GMITable unless the column event_url has a url inside that matches to any of the urls inside gmiurls inside the GMITable
I dont have anycode for this apart from this at the moment
#GMI = GMITable.all

You can easily achieve the result by using a LEFT OUTER JOIN from Table A to Table B, as described in this visual explanation.
Specifically, what you want is:
To produce the set of records only in Table A, but not in Table B, we perform the same left outer join, then exclude the records we don't want from the right side via a where clause.
In your question is not clear how the tables are called, and how they relate each other. However, to achieve the result simply perform a join between the tables using the ActiveRecord join method
TableA.joins('LEFT OUTER JOIN TableB on TableA.field = TableB.field')
and select only the items where(TableB.id IS NULL).
You'll have to adapt the example to your needs.

Related

SQL Rollup table is exponentially duplicating rows

Ok, so I have like 7 cost tables. The idea would be to create a flat table that is essentially all of those costs on a single table. At which point we can feed that to a front end, and when a person picks a specific item, they can see all costs associated with that item.
I have an ItemInfo table, which defines all potential items that may have costs. I then have 7 cost tables, that define all of the individual costs occurred for 7 different phases of that items production.
So, just starting with two of those tables, I have joined the Item table to the Cost1 table, by the ItemID. If I execute that SQL, I get a new table that shows each cost that was accrued in the first phase, along with the relevant bits of data from both tables.
My issue is when I bring the next table in, Cost2.
The Cost1 table has 6,999 entries.
The Cost2 table has 13,743
When I join the ItemID table to the Cost2 table, the resulting table is massive.
I have tried inner joins, left joins, right joins, outer joins, etc.... Regardless of the type of join I try, I do not get 20,742 entries. Which would be the accurate number of entries, based on those two tables being both represented. I have not even attempted moving on to Cost3 through Cost7, as I can't even get the first two to display properly.
I suspect the answer may lie in grouping, but I'm not sure how to do that in a way that would retain the individual cost items from each page.
I thought I understood joins fairly well, and I think I do when it is just 2 tables. What I don't understand is if I tell the first 2 tables to only grab the matching items between them, and then I tell a second set of tables to do the same thing... why does it then seem to try and match cost1 to cost2, even though the ItemID table is the only one I am trying to link them too?

DB grid : How to use a column of the current row of one as an index into another?

I am not sure if the question title is clear enough, please feel free to edit it.
Basically, I have two DB grids which reflect two database tables, each grid showing one.
When the user selects a row in the first table (let's call it oders), I want to update the second with details of any rows matching a column of the selected row of the first table.
Say, for instance that table orders has a column customer_id and I want to populate the second table (let's call it order_details) with details of all orders from that customer, one order per row.
I can connect up 2 # datasource, query and connection to the two TDbGrids, but I am stuck as to how to code order_details SQL.
The SQL for orders is just SELECT * from orders, but the other?
I want something like SELECT * from order_details WHERE cutomer_id=<orderQuery>.currentRow.FieldByName("customer_id").AsInteger - but I don't know how to do that ...
Can someone help me with some Delphi code?
Also, once I set up that relationship, will selecting a new row in the orders DB grid automatically update the order_details DB grid? Or do I need to add code for that.
P.s I know that there is no books tag anymore (more's the pity), but can someone recommend a good book which explains the fundamentals of programming DB aware controls? I obviously need one. Thanks
Use a parameterized query for the detail (child) database:
SELECT * FROM Order_Details od WHERE od.CustomerID = :CustomerID
Then set the child query's MasterSource to the parent (Order) datasource, and the MasterFields to CustomerID. (If there are multiple columns that link the two, separate them by ;, as in CustomerID;OrderNumber.)
Every time you scroll the parent (change the selected record in the parent DBGrid), the child query will be executed with the ID of the parent row passed as a parameter automatically.

Delphi - TUpdateObject versus OnUpdateRecord for a join SQL statement

I have a pFibdataset(which is working similar to BDEDataset) in which I need to make the following join selection
select table.Name as name,
table1.Name as name_1,
table2.Name as name_2
from table
left join table table_1 on table.id=table_1.id
left join table table_2 on table.id=table_2.id
Fields name, name_1 and name_2 are linked to some data-aware edits. Now, I want after I'm modifying(update,delete,insert operations) the name,name_1 and name_2 fields to be updated in the tables. Based on the wiki Using_Multiple_Update_Objects_Index I can use UpdateObjects, or OnUpdateRecord event.
The problem is that I don't understand how this need to be implemented. I have the join select on the query, how I need to define and work with name_1 and name_2 fields. Can someone provide me an example for this?
I know how to use subqueries in order to accomplish this. I need to see how can I can make it by using UpdateObjects or OnUpdateRecord.
TpFibUpdateObject works like a trigger on client side. To make it work, set the following properties:
DataSet - dataset (master) to monitor
KindUpdate - Insert/Update/Delete - action to monitor
SQL - command to execute when action is fired, params are taken from DataSet
ExecuteOrder - AfterDefault/BeforeDefault - probably you need after / master
BUT, instead using a lot of UpdateObject components and such tangled approach, I recommend two alternative (read better) ways:
Updatable view. It will work like a "virtual table". Create a view that joins these theee tables and write Before Insert/Update/Delete triggers. In Delphi use it as a regular table: select from view / insert into view / update view and delete from view. Anyway I suppose you need in many places these tables linked toghether.
Use EXECUTE BLOCK statements in your TpFIBDataSet SQLs. Insert / Update / Delete in a batch all tables.
Solution : OnUpdateRecord it must be created an TUpdateObject for each field from the joined table.
UpdateObjectvariable.DataSet := Dataset;
fill the SQL text
Apply.
After all update objects are set, UpdateAction := uaApplied; must be called.

SubSonic 3 ActiveRecord Fluent Query Multiple Join

I'm trying to do a multiple join to a second column that is referenced from the first join. So in effect find out which stores the product is in.
var q = new MyDB().SelectColumns(Store.NameColumn)
.From<Product>()
.InnerJoin<Shelf>(Product.ShelfIdColumn, Shelf.IdColumn)
.InnerJoin<Store>(Shelf.StoreIdColumn, Store.IdColumn)
.Where(Product.IdColumn).IsEqualTo(5);
The problem is that SubSonic is trying to join the Store table directly to the Product table. I see in the source the comment:
//the assumption here is that the FromTable[0] is the table to join from
So every join is going to be attempted on the Product table. 2.1 had the option of passing in qualified names for the join. Is there a way around this or should I start writing my own fix to allow me to pass in qualified names again?

Deleting rows in joined tables using ADO

Now I have seen this question in another forum but it didn't had an acceptable answer.
Suppose I have two tables, the Groups table and the Elements table. The tables have no defined relationships. The Elements table has an IdGroup field that refers to the IdGroup (PK) field of the Groups table.
I use the following query through an ADO recordset to populate the tables values to a datagrid:
SELECT Elements.*, Groups.GroupName
FROM Elements
INNER JOIN Groups ON Elements.IdGroup = Groups.IdGroup
From that grid I want to press Delete in order to delete an Element. Here is my problem. When I used DAO, the DAO Delete() function deleted only the record in the Elements group. This was the expected behavior.
When I changed to ADO, the Delete() function deleted records in both tables, the element record and the group to which the element belonged!
Is there any way to reproduce the DAO behavior in ADO without having to define relationships into the tables?
Note: I know there are alternatives (executing DELETE querys could do the job). Just show me a way to do this in ADO, or say it cannot be done.
Rewrite you query to:
replace the INNER JOIN with a WHERE clause consisting of an EXISTS;
use a subquery in the SELECT clause to return the value of Groups.GroupName.
Example:
SELECT Elements.*,
(
SELECT Groups.GroupName
FROM Groups
WHERE Elements.IdGroup = Groups.IdGroup
)
FROM Elements
WHERE EXISTS (
SELECT *
FROM Groups
WHERE Elements.IdGroup = Groups.IdGroup
);
I've tested this using SQL Server 2008 with a ADO recordset set as the DataSource property of a Microsoft OLEDB Datagrid Control (MSDATGRD.OCX) then deleting the row via the gird (I assume you are doing something similar) and the row is indeed deleted from table Elements only (i.e. the row in Groups remains undeleted).
Note the revised query may have a negative impact on performance when fetching rows.

Resources