Sistemimi yükselttim ve üzerinde çalıştığım bir web uygulaması için php ile MySql 5.7.9 yükledim. Dinamik olarak oluşturulan bir sorgum var ve MySql'in eski sürümlerinde çalıştırıldığında sorunsuz çalışıyor. 5.7'ye yükselttiğimden beri bu hatayı alıyorum:
SELECT listesinin 1 numaralı ifadesi GROUP BY cümlesinde değildir ve şunları içerir toplanmamış sütun 'support_desk.mod_users_groups.group_id' olan GROUP BY cümlesindeki sütunlara işlevsel olarak bağımlı değildir; bu sql_mode=only_full_group_by ile uyumsuz
Mysql 5.7 için Sunucu SQL Modları konusundaki Kılavuz sayfasına bakın.
Bana sorun çıkaran sorgu bu:
SELECT mod_users_groups.group_id AS 'value',
group_name AS 'text'
FROM mod_users_groups
LEFT JOIN mod_users_data ON mod_users_groups.group_id = mod_users_data.group_id
WHERE mod_users_groups.active = 1
AND mod_users_groups.department_id = 1
AND mod_users_groups.manage_work_orders = 1
AND group_name != 'root'
AND group_name != 'superuser'
GROUP BY group_name
HAVING COUNT(`user_id`) > 0
ORDER BY group_name
Konuyla ilgili biraz araştırma yaptım, ancak sorguyu düzeltmek için ne yapmam gerektiğini anlayacak kadar only_full_group_by'yi anlamıyorum. Sadece
only_full_group_by` seçeneğini kapatabilir miyim, yoksa yapmam gereken başka bir şey mi var?
Daha fazla bilgiye ihtiyacınız olursa bana haber verin.
Aşağıdakileri uygulayarak only_full_group_by
ayarını devre dışı bırakmayı deneyebilirsiniz:
mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
MySQL 8 NO_AUTO_CREATE_USER
ı kabul etmez, bu nedenle bunun kaldırılması gerekir.
Ben olsam GROUP BY
kısmına sadece group_id
eklerdim.
GRUPLAnın parçası olmayan bir sütunu
SEÇerken, gruplar içinde bu sütun için birden fazla değer olabilir, ancak sonuçlarda yalnızca tek bir değer için yer olacaktır. Bu nedenle, veritabanına *genellikle* bu çoklu değerlerin nasıl tek bir değer haline getirileceğinin tam olarak söylenmesi gerekir. Bu genellikle
COUNT(),
SUM(),
MAX()vb. gibi bir toplama fonksiyonu ile yapılır. Genelde* diyorum çünkü diğer popüler veritabanı sistemlerinin çoğu bu konuda ısrarcıdır. Ancak, 5.7 sürümünden önceki MySQL'de varsayılan davranış daha bağışlayıcı olmuştur çünkü şikayet etmeyecek ve ardından keyfi olarak *herhangi bir değer* seçmeyecektir! Ayrıca, gerçekten eskisi gibi aynı davranışa ihtiyaç duyuyorsanız, bu soruya başka bir çözüm olarak kullanılabilecek bir
ANY_VALUE()işlevi de vardır. Bu esnekliğin bir bedeli vardır çünkü deterministik değildir, bu nedenle buna ihtiyaç duymak için çok iyi bir nedeniniz yoksa tavsiye etmem. MySQL artık
only_full_group_by` ayarını iyi nedenlerden dolayı varsayılan olarak açıyor, bu nedenle buna alışmak ve sorgularınızı buna uygun hale getirmek en iyisidir.
Peki neden yukarıdaki basit cevabım? Birkaç varsayımda bulundum:
group_id
benzersizdir. Mantıklı görünüyor, sonuçta bu bir 'ID'.
group_name
de benzersizdir. Bu o kadar da makul bir varsayım olmayabilir. Durum böyle değilse ve bazı yinelenen grup_adları
varsa ve daha sonra GROUP BY
kısmına group_id
ekleme tavsiyemi uygularsanız, aynı ada sahip gruplar artık sonuçlarda ayrı satırlara sahip olacağından artık eskisinden daha fazla sonuç elde ettiğinizi görebilirsiniz. Bana göre bu, veritabanı sessizce keyfi bir değer seçtiği için bu yinelenen grupların gizlenmesinden daha iyi olacaktır!
Ayrıca, birden fazla tablo söz konusu olduğunda tüm sütunları tablo adları veya diğer adlarıyla nitelendirmek de iyi bir uygulamadır...
SELECT
g.group_id AS 'value',
g.group_name AS 'text'
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id
WHERE g.active = 1
AND g.department_id = 1
AND g.manage_work_orders = 1
AND g.group_name != 'root'
AND g.group_name != 'superuser'
GROUP BY
g.group_name,
g.group_id
HAVING COUNT(d.user_id) > 0
ORDER BY g.group_name
Mevcut sorgunuzda herhangi bir değişiklik yapmak istemiyorsanız aşağıdaki adımları izleyin -
kutunuza vagrant ssh
Tip: sudo vim /etc/mysql/my.cnf
Dosyanın en altına gidin ve ekleme moduna girmek için A
yazın
Kopyala ve yapıştır
[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Giriş modundan çıkmak için esc
yazın
Kaydetmek ve vim'i kapatmak için :wq
yazın.
MySQL'i yeniden başlatmak için sudo service mysql restart
yazın.