连接3个表时,提取所有第一个表记录时出现问题

时间:2018-11-04 13:00:14

标签: mysql mysql-workbench

表是服务,计划,订阅。要求是获取“服务”表中的所有记录,但应基于最多的订阅计数对记录进行排序。我能够根据加入条件获取记录,但是无法获取没有订阅的Service表中的记录。

请注意。每个服务记录都有一个计划。但是可以有没有订阅的服务。

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.github.rubensousa.bottomsheetbuilder.BottomSheetBuilder;
import com.github.rubensousa.bottomsheetbuilder.BottomSheetMenuDialog;
import com.github.rubensousa.bottomsheetbuilder.adapter.BottomSheetItemClickListener;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MergingMediaSource;
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import com.nbsp.materialfilepicker.MaterialFilePicker;
import com.nbsp.materialfilepicker.ui.FilePickerActivity;

import java.util.regex.Pattern;

public class SimpleVideoStream extends AppCompatActivity implements ExoPlayer.EventListener {

    public static final int PERMISSIONS_REQUEST_CODE = 0;

    SimpleExoPlayerView playerView;
    SimpleExoPlayer player;
    DataSource.Factory dataSourceFactory;
    MediaSource videoSource;
    BottomSheetMenuDialog menu, subtitle, time;

    TextView video_title;

    String title, path;
    Boolean showTitle = true, showSub = false;
    int timeId = 1;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Bundle b = getIntent().getExtras();
        title = b.getString("mediaTitle");
        path = b.getString("mediaUrl");

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        playerView = (SimpleExoPlayerView) findViewById(R.id.exo_player_view);
        video_title = (TextView) findViewById(R.id.video_title);
        video_title.setText(title);

        if (title.equals("")) {
            showTitle = false;
            video_title.setVisibility(View.INVISIBLE);
        }

        // 1. Create a default TrackSelector
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

        // 2. Create a default LoadControl
        LoadControl loadControl = new DefaultLoadControl();

        // 3. Create the player
        player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
        playerView.setPlayer(player);
        playerView.setKeepScreenOn(true);
        playerView.setRewindIncrementMs(5 * 1000);
        playerView.setFastForwardIncrementMs(5 * 1000);

        // Produces DataSource instances through which media data is loaded.
        dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "ExoPlayer"));

        // Produces Extractor instances for parsing the media data.
        final ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

        // This is the MediaSource representing the media to be played.
        videoSource = new ExtractorMediaSource(Uri.parse(path), dataSourceFactory, extractorsFactory, null, null);

        // Prepare the player with the source.
        player.addListener(this);
        player.prepare(videoSource);
        playerView.requestFocus();
        player.setPlayWhenReady(true);// to play video when ready. Use false to pause a video

        final ImageView option = (ImageView) findViewById(R.id.exo_option);
        option.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Menu();
            }
        });
    }


    @Override
    protected void onPause() {
        super.onPause();
        if (player != null) {
            player.setPlayWhenReady(false); //to pause a video because now our video player is not in focus
        }
    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
    }

    @Override
    public void onLoadingChanged(boolean isLoading) {
    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        switch (playbackState) {
            case ExoPlayer.STATE_BUFFERING:
                //You can use progress dialog to show user that video is preparing or buffering so please wait
                break;
            case ExoPlayer.STATE_IDLE:
                //idle state
                break;
            case ExoPlayer.STATE_READY:
                // dismiss your dialog here because our video is ready to play now
                break;
            case ExoPlayer.STATE_ENDED:
                // do your processing after ending of video
                break;
        }
    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
        // show user that something went wrong. I am showing dialog but you can use your way
        AlertDialog.Builder adb = new AlertDialog.Builder(this);
        adb.setTitle("Could not able to stream video");
        adb.setMessage("It seems that something is going wrong.\nPlease try again.");
        adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                finish(); // take out user from this activity. you can skip this
            }
        });
        AlertDialog ad = adb.create();
        ad.show();
    }


    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
    }

    @Override
    public void onRepeatModeChanged(int repeatMode) {
    }

    @Override
    public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
    }

    @Override
    public void onPositionDiscontinuity(int reason) {
    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
    }

    @Override
    public void onSeekProcessed() {
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
    }

    public void Menu() {
        String sub = showSub ? "Show" : "Hide";
        String time = String.valueOf(timeId * 5);
        String titleCheck = showTitle ? "Show" : "Hide";
        menu = new BottomSheetBuilder(this)
                .setMode(BottomSheetBuilder.MODE_LIST)
                .setItemTextColor(Color.parseColor("#000000"))
                .setBackgroundColor(Color.parseColor("#ffffff"))
                .addItem(0, "Network flow", R.drawable.ic_info_outline_black_24dp)
                .addItem(1, "Subtitle • " + sub, R.drawable.ic_subtitles_black_24dp)
                .addItem(2, "Change time • " + time, R.drawable.ic_timelapse_black_24dp)
                .addItem(3, "Title • " + titleCheck, R.drawable.ic_title_black_24dp)
                .expandOnStart(true)
                .setItemClickListener(new BottomSheetItemClickListener() {
                    @Override
                    public void onBottomSheetItemClick(MenuItem item) {
                        if (item.getItemId() == 0) {
                            NetworkFlow();
                        } else if (item.getItemId() == 1) {
                            Subtitle();
                        } else if (item.getItemId() == 2) {
                            Time();
                        } else if (item.getItemId() == 3) {
                            if (!title.equals("")) {
                                showTitle = !showTitle;
                                video_title.setVisibility((video_title.getVisibility() == View.VISIBLE) ? View.INVISIBLE : View.VISIBLE);
                            }
                        }
                    }
                }).createDialog();
        menu.show();
    }

    public void Subtitle() {
        subtitle = new BottomSheetBuilder(this)
                .setMode(BottomSheetBuilder.MODE_LIST)
                .setItemTextColor(Color.parseColor("#000000"))
                .setBackgroundColor(Color.parseColor("#ffffff"))
                .addItem(0, "Add Url", null)
                .addItem(1, "Add file", null)
                .addItem(2, "Subtitle Size, Font and Color", null)
                .addItem(3, "Remove subtitle", null)
                .expandOnStart(true)
                .setItemClickListener(new BottomSheetItemClickListener() {
                    @Override
                    public void onBottomSheetItemClick(MenuItem item) {
                        if (item.getItemId() == 0) DialogSubtitle();
                        if (item.getItemId() == 1) {
                            checkPermissionsAndOpenFilePicker();
                        }
                        if (item.getItemId() == 2) {
                            Intent intent = new Intent(Settings.ACTION_CAPTIONING_SETTINGS);
                            startActivity(intent);
                        }
                        if (item.getItemId() == 3) {
                            showSub = false;
                            final ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
                            videoSource = new ExtractorMediaSource(Uri.parse(path), dataSourceFactory, extractorsFactory, null, null);
                            player.prepare(videoSource, false, false);
                        }
                    }
                }).createDialog();
        subtitle.show();
    }

    public void DialogSubtitle() {
        LayoutInflater inflater = getLayoutInflater();
        final View layout = inflater.inflate(R.layout.custom_alertdialog, null);
        final EditText url_ele = (EditText) layout.findViewById(R.id.url);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Add Subtitle");
        builder.setCancelable(true);

        builder.setPositiveButton(
                "Ok",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        String sub = url_ele.getText().toString();
                        if (!sub.equals("")) {
                            addSub(sub);
                        }
                        dialog.cancel();
                    }
                });

        builder.setNegativeButton(
                "Close",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alert = builder.create();
        alert.setView(layout);
        alert.show();
    }

    public void Time() {
        Integer[] array = new Integer[13];
        for (int i = 0; i < 13; i++)
            array[i] = timeId == i ? R.drawable.ic_check_black_24dp : R.drawable.ic_more_vert_white_24dp;
        time = new BottomSheetBuilder(this)
                .setMode(BottomSheetBuilder.MODE_LIST)
                .setItemTextColor(Color.parseColor("#000000"))
                .setBackgroundColor(Color.parseColor("#ffffff"))
                .addItem(0, "0", array[0])
                .addItem(1, "5", array[1])
                .addItem(2, "10", array[2])
                .addItem(3, "15", array[3])
                .addItem(4, "20", array[4])
                .addItem(5, "25", array[5])
                .addItem(6, "30", array[6])
                .addItem(7, "35", array[7])
                .addItem(8, "40", array[8])
                .addItem(9, "45", array[9])
                .addItem(10, "50", array[10])
                .addItem(11, "55", array[11])
                .addItem(12, "60", array[12])
                .expandOnStart(true)
                .setItemClickListener(new BottomSheetItemClickListener() {
                    @Override
                    public void onBottomSheetItemClick(MenuItem item) {
                        Log.v("ok", " click3-" + item.getTitle());
                        timeId = item.getItemId();
                        int t = Integer.parseInt(String.valueOf(item.getTitle()));
                        playerView.setRewindIncrementMs(t * 1000);
                        playerView.setFastForwardIncrementMs(t * 1000);
                    }
                }).createDialog();
        time.show();
    }

    public void NetworkFlow() {
        LayoutInflater inflater = getLayoutInflater();
        final View layout = inflater.inflate(R.layout.custom_alertdialog, null);
        final EditText url_ele = (EditText) layout.findViewById(R.id.url);
        url_ele.setText(path);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Network flow");
        builder.setCancelable(true);

        builder.setPositiveButton(
                "Ok",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        String sub = url_ele.getText().toString();
                        if (!sub.equals("")) {
                        }
                        dialog.cancel();
                    }
                });

        builder.setNegativeButton(
                "Close",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alert = builder.create();
        alert.setView(layout);
        alert.show();
    }

    private void checkPermissionsAndOpenFilePicker() {
        String permission = Manifest.permission.READ_EXTERNAL_STORAGE;

        if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
            /*if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                showError();
            } else {*/
            ActivityCompat.requestPermissions(this, new String[]{permission}, PERMISSIONS_REQUEST_CODE);
            //}
        } else {
            openFilePicker();
        }
    }

    private void showError() {
        Toast.makeText(this, "Allow external storage reading", Toast.LENGTH_SHORT).show();
    }

    private void openFilePicker() {
        new MaterialFilePicker()
                .withActivity(this)
                .withRequestCode(PERMISSIONS_REQUEST_CODE)
                .withFilter(Pattern.compile(".*\\.srt$"))
                .withHiddenFiles(true)
                .start();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PERMISSIONS_REQUEST_CODE && resultCode == RESULT_OK) {
            String sub = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH);
            addSub(sub);
        }
    }

    private void addSub(String sub) {
        showSub = true;
        Format textFormat = Format.createTextSampleFormat(null, MimeTypes.APPLICATION_SUBRIP, null, Format.NO_VALUE, Format.NO_VALUE, "en", null, Format.OFFSET_SAMPLE_RELATIVE);
        MediaSource textMediaSource = new SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(sub), textFormat, C.TIME_UNSET);
        videoSource = new MergingMediaSource(videoSource, textMediaSource);
        player.prepare(videoSource, false, false);
    }

}

有人可以调查这个问题并寻求帮助。

2 个答案:

答案 0 :(得分:1)

这可能是表之间的三种方式的联接,按订阅而不是按计划进行汇总。像这样:

SELECT s.*
FROM service s
LEFT JOIN plan p
    ON s.service_id = p.service_id
LEFT JOIN subscribe su
    ON p.plan_id = su.plan_id
GROUP BY
    s.service_id
ORDER BY
    COUNT(su.subscribe_id) DESC;

如果您还想选择订阅计数,则可以将COUNT(su.subscribe_id)项添加到select子句中。请注意,在从service_id表中选择所有列的同时,仅通过service进行聚合,在此假设service_id是该表中的主键是有效的。

答案 1 :(得分:0)

最简单的答案是,您需要左连接,以便可以获取服务中的所有记录+订阅中匹配的任何记录。

SELECT DISTINCT s.service_id 
FROM service s 
JOIN plan p on s.service_id=p.service_id 
left join subscribe su on p.plan_id=su.plan_id 
WHERE
(s.status='Published' AND s.is_active=1) 
GROUP BY su.plan_id 
ORDER BY COUNT(isnull(su.subscribe_id,0)) DESC

此外,您可能希望将计数移到选择部分。像这样:

select * from 
SELECT  s.service_id, COUNT(isnull(su.subscribe_id,0)) as [cnt]
FROM service s 
JOIN plan p on s.service_id=p.service_id 
left join subscribe su on p.plan_id=su.plan_id 
WHERE
(s.status='Published' AND s.is_active=1) 
GROUP BY su.plan_id ) A
ORDER BY  [cnt] DESC

我对列别名使用了SQL Server约定。如果您使用的是其他DBMS,请相应地进行更改。如果您遇到服务没有计划的情况,也应该将其更改为左联接。