Hey I am an absolute ruby noob and hope you could help me.
I want to do a lot of SQL-querys with different departments (Department A,B, C....)
I want to save the departments to an array and iteratethrough it, use loops and so on.
This is my old code:
#!/usr/bin/ruby
require 'mysql2'
##Connect to my Database
db = Mysql2::Client.new(:host => "localhost", :username => "MyUserName", :password => "MyPassword", :port => 3306, :database => "MyTest-Database" )
#Mysql querys
sql_A= "SELECT RMKPI FROM `Table1` WHERE `Department` = 'A' "
sql_B= "SELECT RMKPI FROM `Table1` WHERE `Department` = 'B' "
#Execute the querys
results_PO = db.query(sql_A)
results_DevMuM = db.query(sql_A)
This is my Pseudocode:
Array1[A,B,...]
loop
sql_Array1[x]="SELECT ...WHERE `Department`= Array1[x]"
Array1[x+1]
How can I do this?
Thanks a lot
DEPARTMENTS = %w|A B C|
results = DEPARTMENTS.map do |department|
query = "SELECT RMKPI FROM `Table1` WHERE `Department` = '#{department}'"
[department, db.query(query)]
end.to_h
Now you have a hash of { departments ⇒ results }. To access results for a given department, use:
results['A']
Sidenote: I would suggest you to google for ActiveRecord or any other ROM to simplify and make safer the work with database queries.
Related
Need to update a field within my mysql db. Would like to use the following query within rails:
update users set exported = TRUE where id = #{name[12]}
Currently, have the following:
db = Mysql2::Client.new( :host => 'localhost', :username => 'username', :password => 'password', :database => 'database')
results = db.query("select * from users where start_date is not NULL AND exported = 0").each(:as => :array)
results.each do |name|
db.query("update users set exported = TRUE where id = #{name[12]}")
end
index 12 is equal to the UID.
I would suggest that you use ActiveRecord for database calls when you are using Ruby on Rails.
I assume that you have at least a basic User model like this:
class User < ApplicationRecord
end
With an User model like that your query could look like this:
User.where.not(start_date: nil).where(exported: false).update_all(exported: true)
If you're using rails, I'd suggest using ActiveRecord. Your update will be:
#users = User.find(:all, :where => 'start_date is not null and exported = 0 and id = ?', name[12])
#users.each{ |user|
user.exported = true
user.save!
}
Hope that helps! Leave a comment if you need further help.
I am trying to do a check against 3 table that I join together. I do not want to use the real table name hard coded as my project is highly under develop and table prefix may be changed. What is the best way in Yii2 to select from 3 table where I have where statement on the joined table?
I can get what I want from the code below. But as I said, I do not want to use the table alias hard coded. Any idea how to fix this or suggestion of other ideas would be very appreciated.
$userId = Yii::$app->user->id;
$result = \app\models\UserPermission::find()->joinWith([
'permission',
'permission.service'
])->where([
'prefix_user_permission.user_id' => $userId,
'prefix_permission.flag' => Permission::LOGIN,
'prefix_service.login_available' => Service::LOGIN_AVAIABLE,
])->all();
I would like to end up with this query:
SELECT *
FROM `prefix_user_permission` `up`
INNER JOIN `prefix_permission` `p` ON `up`.`permission_id` = `p`.`id`
INNER JOIN `prefix_service` `s` ON `p`.`service_id` = `s`.`id`
WHERE (`up`.`user_id`=43)
AND (`p`.`flag`='LOGIN')
AND (`s`.`login_available`=1);
The table prefix can be configured using the 'tablePrefix' param along with the main db config as follows:
'components' => [
'db' => [
//other db config params
'tablePrefix' => 'pre_'
]
This prefix can be used as follows:
There's a special variant on this syntax specific to tablenames: {{%Y}} automatically appends the application's table prefix to the provided value, if a table prefix has been set:
$sql = "SELECT COUNT([[$column]]) FROM {{%table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();
Or if you are using active record for models then you can also use the tableName() function to replace the hard-coded table names.
I am trying to run a query, that has a subselect in it. I have set up the Manager method, and everything works fine. The only problem is i dont know how to proceed with this query :
SELECT * FROM tableA WHERE
name = 'Me' AND
class='Tester' AND
( ( Department IN ( SELECT Department FROM
tableB WHERE
leader = 'Joe')
OR
Leader in ('','all') )
);
Its important to remember that tableA and tableB are 2 different tables . As of now i have reached this query :
my #leader = ('','all');
DB::tableA::Manager->get_tableA ( with_object => ['tableB'] ,
query => [ name => 'Me',
class => 'Tester',
OR => [
leader => \#leader,
Department => [*** this is
where i have to make the sub select.
Dont know how though **** ]
]
],
debug => 1);
please help so that i can add that sub query to this main query
Thanks in advance
You can use the clauses function to include arbitrary clauses in the query's WHERE portion.
It would look like this.
DB::tableA::Manager->get_tableA ( with_object => ['tableB'] ,
query => [
name => 'Me',
class => 'Tester',
],
clauses => ["( Department IN ( SELECT Department FROM tableB WHERE leader = 'Joe' ) OR Leader in ('','all') )"
);
CPAN: Rose::DB::Object::QueryBuilder, Functions
Is there a way to execute a SQL String as a query in Zend Framework 2?
I have a string like that:
$sql = "SELECT * FROM testTable WHERE myColumn = 5"
now I want to execute this string directly.
Just pass the sql string to your db adapter like this:
$resultSet = $adapter->query($sql, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
And if you want to pass parameters:
$sql = "SELECT * FROM testTable WHERE myColumn = ?";
$resultSet = $adapter->query($sql, array(5));
EDIT: Please note that the query method does not always returns a resultset. When its a resultset producing query(SELECT) it returns a \Zend\Db\ResultSet\ResultSet otherwise(INSERT, UPDATE, DELETE, ...) it will return a \Zend\Db\Adapter\Driver\ResultInterface.
And when you leave the second Parameter empty you will get a \Zend\Db\Adapter\Driver\StatementInterface which you can execute.
use Zend\Db\Sql\Sql;
use Zend\Db\Adapter\Adapter;
$dbAdapterConfig = array(
'driver' => 'Mysqli',
'database' => 'dbname',
'username' => 'dbusername',
'password' => 'dbuserpassword'
);
$dbAdapter = new Adapter($dbAdapterConfig);
$sql = new Sql($dbAdapter);
$select = $sql->select();
$select->from('testTable');
$select->where(array('myColumn' => 5));
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
S. docu: Zend\Db → Zend\Db\Sql
If you are using tableGateway, you can run your raw SQL query using this statement,
$this->tableGateway->getAdapter()->driver->getConnection()->execute($sql);
where $sql pertains to your raw query. This can be useful for queries that do not have native ZF2 counterpart like TRUNCATE / INSERT SELECT statements.
If you have EntityManager $em on your hands, you can do something like this:
$select = $em->getConnection()->executeQuery("
SELECT a.id, a.title, a.announcement, asvc.service_id, COUNT(*) AS cnt,
GROUP_CONCAT(asvc.service_id SEPARATOR \", \") AS svc_ids
FROM article AS a
JOIN articles_services AS asvc ON asvc.article_id = a.id
WHERE
asvc.service_id IN (
SELECT tsvc.service_id
FROM tender AS t
JOIN tenders_services AS tsvc ON tsvc.tender_id = t.id
WHERE t.id = :tenderId
)
GROUP BY a.id
ORDER BY cnt DESC, a.id DESC
LIMIT :articlesCount
", [
'articlesCount' => 5,
'tenderId' => $tenderId,
], [
'articlesCount' => \PDO::PARAM_INT,
]);
$result = $select->fetchAll(); // <-- here are array of wanted rows
I think this way to execute complex queries is best for Zend. But may be I'm not very smart in Zend still. Will glad to see if it helps to someone.
$conditions = Array
(
[table] => products_pages
[alias] => ProductsPage
[type] => inner
[foreignKey] =>
[conditions] => Array
(
[0] => ProductsPage.product_id = Product.id
)
)
I'm trying to set up NOT EXISTS conditions, like the following SQL statement:
SELECT * FROM products_pages,products
WHERE NOT EXISTS (SELECT id
from products_pages
where products_pages.product_id = products.id)
So basically select any product that doesn't exist in the products_pages table.
What is the proper way to format that SQL statement for CakePHP and replace it here:
[conditions] => Array
(
[0] => (What's the proper way to insert above SQL here?
)
Would really appreciate your help guys, I've been trying to figure this out for about 5 hours with no luck. Thanks!
You can always use query if you don't find the way to do it with CakePHP:
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-query
In this case security wouldn't be compromised as you are not using any input.
Anyway, something simple would be just to do it in more than one step:
//selecting the products in the productcs_pages table
$productsWithPages = /* query to get them*/
//getting an array of IDs
$productsWidthPagesIds = Hash::extract($productsWithPages, '{n}.Product.id');
//doing the NOT IN to select products without pages
$productsWithoutPages= $this->Product->find('all',
array('conditions' =>
array( 'NOT' => array('Product.id' => $productsWidthPagesIds )
)
);